October: Add magic method using add dynamic method doesn't work when extend model

Created on 10 Nov 2016  Â·  8Comments  Â·  Source: octobercms/october

Hi,

I know we can extend the model and add method using addDynamicMethod. But, when I'm trying to add magic method it seems doesn't work. It just always references to the magic method of the parent class of class we extended in plugin. Is that possible and how to do that?

Here's my code:

Plugin.php

    public function boot()
    {
        \System\Models\File::extend(function($model) {
            $model->addDynamicMethod('__call', function($method, $params) {
                return 'You are trying to call ' . $method . ' method.';
            });
        });
    }

Execute the command in tinker

>>> System\Models\File::hello()
BadMethodCallException with message 'Call to undefined method October\Rain\Database\QueryBuilder::hello()'

Thanks.

Question

Most helpful comment

I think you simply want a behavior

<?php namespace Rahman\ImagExtend\Classes;

class Image extends \October\Rain\Extension\ExtensionBase
{
    /**
     * @var Reference to the extended object.
     */
    protected $file;

    /**
     * Constructor
     */
    public function __construct($file)
    {
        $this->file = $file;
    }

    public static function hello()
    {
        return 'say hello';
        //TODO: Get Image width using Imagick::getImageWidth()
    }
}


\System\Models\File::extend(function($file) {
    $file->implement[] = 'Rahman.ImagExtend.Classes.Image';
});


echo \System\Models\File::hello();

See the documentation on behaviors for more details:
http://octobercms.com/docs/services/behaviors

All 8 comments

To clarify, you are trying to add a dynamic __magic method? I'm not sure this will work. Please provide more detail in your issues so we can help better, code examples, etc.

@daftspunk I'm sorry. I updated my question.

Thanks. This is definitely not supported at this stage. Can you give more details about your problem, instead of the proposed solution, perhaps there is another solution we can suggest. For more info on presenting your problem see http://mywiki.wooledge.org/XyProblem.

Thank you, @daftspunk.

I just want to create a plugin and extend System\Models\File. The plugin provides convenience to give ability if there is an image file. Such as:

  • image.width, image.height to get image width and height
  • image.resolution to get image resolution
  • etc

I know we can add every single dynamic method by extending the model. But, I won't do that every time I add a new method in my helper class and should add a dynamic method too.

Maybe I have to get a second option by adding a dynamic method such as for example info , so I can get image width by using image.info.width.

Lastly, I trying to add this code directly to System\Models\file and then works as I expected. But I hope someone can give me the advice to extending the model as I expect 😄

    public function __call($method, $params)
    {
        $image = new \Rahman\ImagExtend\Classes\Image;

        if (method_exists($image, $method)) {
            return call_user_func_array([$image, $method], $params);
        }

        return Parent::__call($method, $params);
    }
<?php namespace Rahman\ImagExtend\Classes;

class Image 
{
    public static function hello()
    {
        return 'say hello';
        //TODO: Get Image width using Imagick::getImageWidth()
    }
}
>>> $file = System\Models\File::hello();
=> "say hello"

>>> $file = System\Models\File::first();
=> System\Models\File {#947
     id: 1,
     disk_name: "",
     file_name: "",
     file_size: 0,
     content_type: "",
     title: null,
     description: null,
     field: null,
     sort_order: 1,
     created_at: "2016-11-10 13:43:39",
     updated_at: "2016-11-10 13:43:39",
   }
>>>

Thanks

I think you simply want a behavior

<?php namespace Rahman\ImagExtend\Classes;

class Image extends \October\Rain\Extension\ExtensionBase
{
    /**
     * @var Reference to the extended object.
     */
    protected $file;

    /**
     * Constructor
     */
    public function __construct($file)
    {
        $this->file = $file;
    }

    public static function hello()
    {
        return 'say hello';
        //TODO: Get Image width using Imagick::getImageWidth()
    }
}


\System\Models\File::extend(function($file) {
    $file->implement[] = 'Rahman.ImagExtend.Classes.Image';
});


echo \System\Models\File::hello();

See the documentation on behaviors for more details:
http://octobercms.com/docs/services/behaviors

Wow, Thanks!

You're welcome. Don't forget to change your file path and namespace to Rahman\ImagExtend\Behaviors to follow convention.

Ok. Thanks for your advice.

On Nov 14, 2016 04:12, "Samuel Georges" [email protected] wrote:

You're welcome. Don't forget to change your file path and namespace to
Rahman\ImagExtend\Behaviors to follow convention.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/octobercms/october/issues/2475#issuecomment-260213234,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AIkB_EY47Z2UzgeBr481NFE5ZqTfw-Ubks5q9302gaJpZM4Ku0D-
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ChVuagniaux picture ChVuagniaux  Â·  3Comments

lukaszbanas-extremecoding picture lukaszbanas-extremecoding  Â·  3Comments

dunets picture dunets  Â·  3Comments

LukeTowers picture LukeTowers  Â·  3Comments

Flynsarmy picture Flynsarmy  Â·  3Comments