We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Custom Behaviors Aren't Loading

TL;DR: I have created a custom behavior and done everything I can think of to properly load the class, but I cannot add the behavior to a model due to a classnotfound exception. Where/How should I be loading this custom Behavior?

I am attempting to create a custom behavior -> commentable, to clean up the code project wide for a fairly simple web app.

My thought was to take our currently implemented system (using an endpoint system) to pull comments (our comments table contains all comments, not sepcific to a particular model, so model relationships won't work, unless I am mistaken and a model can have a relationship to something on specific field values -ie the resourceId field matches the class name of the model..)

I have done the following:

  • Began migrating the code
  • Created a directory in my project /app/behaviors
  • Created a file called CommentableBehavior.php to said directory with the following code:
<?php
namespace Phalcon\Mvc\Model\Behavior;

use Phalcon\Mvc\Model\Behavior;
use Phalcon\Mvc\Model\BehaviorInterface;
use Phalcon\Mvc\ModelInterface;

class Commentable extends Behavior implements BehaviorInterface
{

    private $idField = "id";

    public function notify( $eventType, $model ) {

        switch($eventType) {
            case 'afterUpdate':
                // change all the comments for this resource if ID changed

                // change all the comments to deleted if this resource is softdeleted
        }

    }

    public function getComments(ModelInterface $model) {
        $resource_type = get_class($model);
        $resource_id = $mode->readAttribute($this->idField);

         $comments = Comments::find([
        "conditions" => "resource_id=:r_id: AND resource_type=:r_type: AND lft=1",
        "bind" => [
          "r_id" => $resourceId,
          "r_type" => $resourceType
        ]
      ]);

    // Get the comment ordering
    $ordered_comments = Comments::find([
        "conditions" => "resource_id=:r_id: AND resource_type=:r_type:",
        "bind" => [
          "r_id" => $resourceId,
          "r_type" => $resourceType
        ]
      ]);

    $num = 0;
    foreach($ordered_comments as $oc) {
      $comments_order[$oc->id] = ++$num;

    }

    $comments_tree = array();
    foreach ($comments as $comment) {
      $desc = $comment->descendants(null, true);
      array_push($comments_tree, $this->createTree($desc));
    }
    $comments_out->tree = $comments_tree;
    $comments_out->order = $comments_order;

    return $comments_out;

    }

  private function createTree($tree) {
    //same as before
    $currDepth = -1;

    //initilialize result
    $result = array();

    //create path structure for depths
    $path = array();

    //create 'root' node
    $olditem = array('children'=> &$result);

    foreach($tree as $item){
        $item = $item->toAssocArray();
        if($item['lvl'] > $currDepth){
            //remove possible old reference (old depth of other branch
            if(isset($path[$item['lvl']])) unset($path[$item['lvl']]);

            //make sure we have an array entry
            if(!isset($olditem['children'])) $olditem['children'] = array();

            //acquire target
            $path[$item['lvl']] = &$olditem['children'];
        }
        if($item['lvl'] != $currDepth) unset($olditem);
        //set correct target
        $currDepth = $item['lvl'];
        //add item
        $path[$currDepth][] = &$item;
        //copy & remove reference
        $olditem = &$item;
        unset($item);
    }
    //always nice to clean up reference bombs:
    unset($path);
    unset($olditem);

    return $result;
  }

}
  • Added the directory to my config->application as "behaviorsDir"
  • Added the directory to the loader ($loader->registerDirs( ... ) );
  • Updated a model to include:
use Phalcon\Mvc\Model\Behavior\Commentable;

...

  public function initialize()
  {
    $this->setConnectionService('newsdb');
    $this->setSource('wp_posts');
    $this->belongsTo("post_author", "NewsAuthor", "ID");
    $this->hasMany("ID", "NewsMeta", "post_id");
    $this->belongsTo("ID", "NewsTermsRelationships", "object_id");

    $this->addBehavior(new Commentable());

    }

The problem that I am running into is that the behavior isn't adding because of a class not found exception:

 PHP Fatal error:  Class 'Phalcon\\Mvc\\Model\\Behavior\\Commentable' not found in

So, my question is Where should I be saving custom behaviors so they can be used in my app

I have searched the documentation/web and haven't been able to determine where I am going wrong!



85.5k

i hope this will help you

https://forum.phalcon.io/discussion/9193/dynamic-registration-namespaces

i am going to sleep, hopefully if i didnt help you some else will.

Cheers

and my app is multi moduled.

so in my mobules i have "extra" folder called libs, inside i create my helper classes, where I put the "long logic"

and please forgive if i doidnt understand you corretcly

Thanks for the reply. However, though namespaces are "part" of this issue here (and this helped, sort of, it got rid of some errors in the log, but the class still wasn't being loaded and now the log isn't reporting any errors). The larger part is why isn't the Class being loaded?

i hope this will help you

https://forum.phalcon.io/discussion/9193/dynamic-registration-namespaces

i am going to sleep, hopefully if i didnt help you some else will.

Cheers

and my app is multi moduled.

so in my mobules i have "extra" folder called libs, inside i create my helper classes, where I put the "long logic"

and please forgive if i doidnt understand you corretcly



635
Accepted
answer

Sorry if this is a repeat of the reply above, but I think the problem must be this: namespace Phalcon\Mvc\Model\Behavior I think there is a conflict of namespaces unless you have specifically setup your app to allow using the Phalcon namespace in custom classes.

Either way, since behaviors are related to models, how about creating 'Behavior' subdirectory in your models folder? Then you should be able to namespace your behavior as YourModelsNamespace\Behavior without any extra config/worrying about namespacing.

It was exactly that, and that is exactly what I did to resolve.

Sorry if this is a repeat of the reply above, but I think the problem must be this: namespace Phalcon\Mvc\Model\Behavior I think there is a conflict of namespaces unless you have specifically setup your app to allow using the Phalcon namespace in custom classes.

Either way, since behaviors are related to models, how about creating 'Behavior' subdirectory in your models folder? Then you should be able to namespace your behavior as YourModelsNamespace\Behavior without any extra config/worrying about namespacing.

Ok glad to hear it worked out

It was exactly that, and that is exactly what I did to resolve.

Sorry if this is a repeat of the reply above, but I think the problem must be this: namespace Phalcon\Mvc\Model\Behavior I think there is a conflict of namespaces unless you have specifically setup your app to allow using the Phalcon namespace in custom classes.

Either way, since behaviors are related to models, how about creating 'Behavior' subdirectory in your models folder? Then you should be able to namespace your behavior as YourModelsNamespace\Behavior without any extra config/worrying about namespacing.

edited Oct '15

You cant use namespaces from phalcon i think. Also im NOT SURE, but files should be called same as class name.