Change data inside file object?

Let’s say I use thumb and it return a file object.

$file_object = thumb( $page->image(), array('width' => 300) );

I want to change the value of name for example:
http://getkirby.com/docs/cheatsheet/file/name

1. Can I change $file_object->name()?

Can I change the value $file_object->name() somehow? It is “my” object now (returned) so I should be able to control it?

Example

From this:

my-filename

To this:

my-filename-min

2. Can I add a new value to the $file_object?

If the first alternative is not possible, can I add a new value instead, as a function, like this?

echo $file_object->name_min();

3. Can I clone the object to do it?

If none of the above work, can I clone the object somehow to make it work? To add my own data?

I’ve never done something like this, but did you have a look at the toolkit API?

http://getkirby.com/docs/toolkit/api#f
http://getkirby.com/docs/toolkit/api/f/write

Maybe this could be a starting point …

$file->rename() is probably what you are looking for?

http://getkirby.com/docs/cheatsheet/file/rename

@flokosiol @texnixe

No. I want to change what is returned from the object. Not change the file, just the object.

You could probably extend the object with your own custom class as a plugin …?

I use OOP to some extend, but I have no skills in extending objects. I added a question to stackoverflow.

I tried this with no luck

class Foo
{
    public function __call($method, $args)
    {
        if(is_callable(array($this, $method))) {
            return call_user_func_array($this->$method, $args);
        }
        // else throw exception
    }
}

$foo = new Foo;
$foo->cb = function($who) { return "Hello $who"; };
echo $foo->cb('World');

I tried to change $foo to $page for testing, but it does not work because it need the things is in the Foo-class.

Just as a reminder, this is an example of what I want:

echo $page->my_function_call();
echo $file->my_own_function();

…but still keep the current functions inside. $file is a returned object, not a global one.

I still try to merge the two objects together but still no luck. What is wrong?

class Foo {
    function test() {
      return 'whatever';
    }
}

$foo = new Foo;

$new_object = (object) array_merge((array) $foo, (array) $page);

echo $new_object->title();

The error message is

Fatal error: Call to undefined method stdClass::title()

That won’t work, as converting the objects to arrays to merge them removes the reference to the original classes.

Please take a look at the implementation of the File class. It has a __call() method, which gets called for all not explicitly defined methods. It uses the meta() method, which returns $this->cache['meta'], which is an object of type Content.
You can now get the Content object and set your custom data on it. The corresponding methods on the File object should now be callable:

$file_object->meta()->data['name'] = 'my-filename';
echo $file_object->name(); // my-filename

I have not tested this though, so please let me know if that worked and - if not - what the error was.

It seems very nice but it does not work like expected. It does not set “name” to “my-filename”. It still contains the original filename.

My implementation

$file = thumb( $page->image(), array('width' => 300) );
$file->meta()->data['name'] = 'my-filename';
echo $file->name();

…returns…

screenshot-1-12bc573c02cc3997f9b2c0770d6defde

Oh, I missed that you are using thumb(), which works totally differently. It is no File object but a Thumb object, which relies on Media (both are part of the Toolkit).

Media can’t be extended like this though, because it gets its data directly from the file. So what you plan on doing is not directly possible and you will need to choose a different approach:

class CustomMedia extends Media {
  public function name() {
    return 'my-filename';
  }
}

$file = thumb(new CustomMedia($page->image()), array('width' => 300));
echo $file->name(); // my-filename

Again: Untested, but this should work for thumbs.

1 Like

That worked! At least if you add parentheses() after image:

$file = thumb( new CustomMedia( $page->image() ), array( 'width' => 300) );

Yeah, sorry. That was a typo.
Glad it worked. Awesome!