Giter Club home page Giter Club logo

Comments (28)

ADmad avatar ADmad commented on June 15, 2024 1

Few updates have been made to the plugin which should hopefully resolve issues mentioned in this ticket. If anyone is still facing problem please reopen new issue with steps to reproduce.

from footprint.

jadb avatar jadb commented on June 15, 2024

Where is the save being called from?

from footprint.

Cylindric avatar Cylindric commented on June 15, 2024

I have an XpController with an Add() method.

    public function add()
    {
        $xp = $this->Xp->newEntity();
        if ($this->request->is('post')) {
            $xp = $this->Xp->patchEntity($xp, $this->request->data);
            if ($this->Xp->save($xp)) {
                $response = ['result' => 'success', 'data' => $xp];
            } else {
                $response = ['result' => 'fail', 'data' => $xp];
            }
        }

        $this->set('response', $response);
        $this->set('_serialize', ['response']);
    }

My full XpController

from footprint.

jadb avatar jadb commented on June 15, 2024

Weird.. Does your request data contain a user_id by any chance?

from footprint.

waspinator avatar waspinator commented on June 15, 2024

Did you ever get this to work Cylindric? I noticed that you seem to be using https://github.com/ceeram/blame now. I'm having a similar issue.

from footprint.

jadb avatar jadb commented on June 15, 2024

@waspinator do u have a failing test? Would love to get to the end of this.

from footprint.

Cylindric avatar Cylindric commented on June 15, 2024

Sorry, yes I switched to Ceeram/blame just to get going. If I get time I'll try and spin up a test case, but I'm not massively familiar with tests for things like this, so it might take me a bit.

from footprint.

ADmad avatar ADmad commented on June 15, 2024

@Cylindric It's ok if you can't provide a test case. You can try to debug the issue and provide us some specifics about what's causing the problem.

from footprint.

kristiyandobrev avatar kristiyandobrev commented on June 15, 2024

I have the same issue, my options array in the FootprintBehaviour's beforeSave also looks weird:

object(ArrayObject) {
    atomic => true
    associated => [
        'projects' => [],
        'targetcompanies' => [],
        'users' => [],
        'cities' => [],
        'companiestarget' => [],
        'companies' => [],
        'contacttypes' => []
    ]
    checkRules => true
    checkExisting => true
    _primary => true
}

it doesn't contain any _footprint.id plus, if I debug current(Hash::extract((array)$options, $this->config('propertiesMap.' . $field))) it returns false....

from footprint.

jadb avatar jadb commented on June 15, 2024

@kristiyandobrev please answer the following so we can better assist you:

  • what's the behavior's configuration like? (paste it please)
  • what are you trying to do, what's the code for it?
  • finally, what are you expecting?

from footprint.

kristiyandobrev avatar kristiyandobrev commented on June 15, 2024

Alright.

I will start from the last question 😸

finally, what are you expecting?

In my table ContactsTable I have a called created_by_id (note that it's not created_by) which I want to set to the current (logged) user's id, every time I am creating a new database record.

what are you trying to do, what's the code for it?

For the purpose I first install your plugin from the command line like:

composer require muffin/footprint:dev-master

then I add it to my bootstrap.php

Plugin::load('Muffin/Footprint');

As it was required I included the Muffin\Footprint\Auth\FootprintAwareTrait to my AppController:

Link to my AppController

My AuthComponent is configured to use the default Users table which in my case is also called Users therefore I didn't find necessary to add $this->_userModel = 'SomeOtherTable'; in the beforeFilter.

what's the behavior's configuration like? (paste it please)

As I mentioned above I want to set the created_by_id of my every new record ContactsTable to be the current/logged user's id, therefore I am adding the following behaviour to my ContactsTable.

Link to my ContactsTable.php

To sum up, the above doesn't work for me. It inserts empty value for created_by_id in the ContactsTable.

I looked over the plugin, played a little bit with the debug option and what I found was that:

In FootprintListener

public function handleEvent(Event $event, $ormObject, $options)
    {
        $key = $this->config('optionKey');
        if (empty($options[$key]) && !empty($this->_currentUser)) {
            $options[$key] = $this->_currentUser;
        }
        debug($this->config('optionKey'));
    } 

The output of the above is actually a complete (not empty) entity of the logged user. But with further debugging I found that in FootprintBehaviour:

 public function beforeSave(Event $event, Entity $entity, ArrayObject $options)
    {
        $eventName = $event->name();
        $events = $this->config('events');

        $new = $entity->isNew() !== false;

        foreach ($events[$eventName] as $field => $when) {
            if (!in_array($when, ['always', 'new', 'existing'])) {
                throw new UnexpectedValueException(
                    sprintf('When should be one of "always", "new" or "existing". The passed value "%s" is invalid', $when)
                );
            }

            if ($entity->dirty($field)) {
                continue;
            }

            if ($when === 'always' ||
                ($when === 'new' && $new) ||
                ($when === 'existing' && !$new)
            ) {
                $entity->set(
                    $field,
                    current(Hash::extract((array)$options, $this->config('propertiesMap.' . $field)))
                    debug(current(Hash::extract((array)$options, $this->config('propertiesMap.' . $field))));
                );
            }
        }
    }

The output of above debug is false and respectively I see empty value in my DB table (expects UUID not bool) which seems to be strange since the FootprintBehaviour I could actually see the entity that I need.

from footprint.

jadb avatar jadb commented on June 15, 2024

Hmm, this all seems good.

You are saying in the behavior you could see the user entity, in which case it would be an issue with extract that is heavily tested by cake's core.

Or maybe you meant you see the user in the listener? If so, could you please debug($options) really early in the behavior's beforeSave() method?

from footprint.

kristiyandobrev avatar kristiyandobrev commented on June 15, 2024

Here you go:

FootprintBehavior

 public function beforeSave(Event $event, Entity $entity, ArrayObject $options)
    {
        debug($options);
        die();

And the output is:

object(ArrayObject) {
    atomic => true
    associated => [
        'projects' => [],
        'targetcompanies' => [],
        'createdby' => [],
        'cities' => [],
        'companiestarget' => [],
        'companies' => [],
        'contacttypes' => []
    ]
    checkRules => true
    checkExisting => true
    _primary => true
}

Just like in my very first comment.

P.S

My doubts are that FootprintListener's handleEvent is not called at all in the beforeSave

from footprint.

jadb avatar jadb commented on June 15, 2024

The footprint listener is not used by the behavior, it listens to the controller. Am trying to grok this but all seems to be configured correctly.

I noticed you were pre-loading the models before setting up the Auth component which could have consequences. Any reason why you are _pre-_loading the models?

Have you been able to write a failing test?

from footprint.

kristiyandobrev avatar kristiyandobrev commented on June 15, 2024

Any reason why you are pre-loading the models?

Yes I need the for later actions.

Also here is the output of $this-Auth->user();--> LINK

Could it be because the user is not a clear entity but it has some associations ?

from footprint.

jadb avatar jadb commented on June 15, 2024

I can't grok the reason why it would fail. @ADmad any ideas?

from footprint.

ADmad avatar ADmad commented on June 15, 2024

Nope.

from footprint.

mattford avatar mattford commented on June 15, 2024

I'm having the same issue in my project, a little bit of investigation suggests the problem may be in CakePHP itself, as AuthComponent::_getUser() will short-circuit if the user can be retrieved from session storage without firing the Auth.afterIdentify event.

After adding the following on line 690 of AuthComponent, the event is now firing, and the current user gets as far as FootprintListener, but doesn't seem to be getting to the model.

$event = $this->dispatchEvent('Auth.afterIdentify', [$user]);

Going to keep investigating and see if I can find a fix

May be important, the model in question actually extends another model, so I have PostsTable which extends Cake\ORM\Table and QuestionsTable which extends App\Model\Table\PostsTable

Edit: the above doesn't seem to be supported in CakePHP from what I can see reading cakephp/cakephp#4412

Second edit: Now seems to be working without me changing anything at all, might have been entirely due to the extending of the Table classes

from footprint.

ypnos-web avatar ypnos-web commented on June 15, 2024

I also have this problem. I use FootprintBehavior for two tables, with the first it works great, with the second it doesn't.

I put a breakpoint here:

$key = $this->config('optionKey');

And another one here:

What I expect:
The first breakpoint fires at least once before the second breakpoint. (It is true for my table where it works)

What I observe:
The second breakpoint fires first! Variable inspection reveals that data is missing. The first breakpoint then fires several times.

I really do nothing special, I call parent::initialize() before loading models and AppController has the trait (obviously, as it wouldn't work for the other table otherwise). My behavior configuration is dead simple:

Case 1 (works):

        $this->addBehavior('Muffin/Footprint.Footprint', [
            'events' => ['Model.beforeSave' => ['user_id' => 'new']],
        ]);

Case 2 (doesn't work):

        $this->addBehavior('Muffin/Footprint.Footprint', [
            'events' => ['Model.beforeSave' => [
                'owner_id' => 'new',
                'modifiedby_id' => 'existing'
            ]],
        ]);

Thanks for any hints on how to further debug this!

from footprint.

jadb avatar jadb commented on June 15, 2024

Sorry everyone, really short on time, haven't looked into it yet.

If anyone can submit a failing test, it will definitely make things much easier ;)

/cc @ADmad @Phillaf @deizel

from footprint.

stmeyer avatar stmeyer commented on June 15, 2024

I have the same issue by calling $table = TableRegistry::get($tableName); in the Controller::beforeFilter() event.
Sorry, but at the moment i do not have time to create a test case, but maybe this information helps.

from footprint.

kristiyandobrev avatar kristiyandobrev commented on June 15, 2024

I got some inspiration from Footprint plugin and end up with forking and modifying ceeram/blame plugin so that it can use custom fields. See the pull request here.

from footprint.

stmeyer avatar stmeyer commented on June 15, 2024

@kristiyandobrev Thanks for your reply. I was using https://github.com/ceeram/blame before, but this plugin is more flexible. For example in some models i need to insert automated information from models associated to the Users model.

from footprint.

ADmad avatar ADmad commented on June 15, 2024

@stmeyer A table initialized in Controller::beforeRender() won't get the footprint since AuthComponent::startup() has still not run. You can trying changing the auth config checkAuthIn to 'Controller.initialize' to make auth do the authentication check earlier and make user info available in beforeFilter().

from footprint.

stmeyer avatar stmeyer commented on June 15, 2024

@ADmad thanks for the hint. I changed the code so that I don't need to load tables in Controller::beforeFilter(). If it is needed if future, if will test it

from footprint.

ypnos-web avatar ypnos-web commented on June 15, 2024

I finally found the source of my problems based on the discussion about AuthComponent::startup(). I had called loadModel() in my controller's initialize(). This is somewhat sensical, as also components are loaded in initialize().
I suggest to document that this plugin relies on late model loading.

from footprint.

kristiyandobrev avatar kristiyandobrev commented on June 15, 2024

The issues that I mentioned in my previous comment is still not resolved, after the update @ADmad @jadb any ideas ?

from footprint.

ADmad avatar ADmad commented on June 15, 2024

@kristiyandobrev You have messed up the behavior config and nested propertiesMap inside events.

from footprint.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.