Jump to content

Create Pagefile or Pageimage


matjazp
 Share

Recommended Posts

I don't have $my_files_field. I know that Pagefiles are "connected" to the page that has FieldtypeFile, but I actually don't want to add a file to the page, I just want to create a Pagefile object, that has basename, filename, ext, size, url, httpUrl etc. methods/properties.

Link to comment
Share on other sites

Thanx Robin (and Lostkobrakai) for you answers. It would work, but then I would need existing page. Ok, this was just an idea on how to crate fake Pagefile :-)

Let's try this more realistic approach: how to get Pagefile object if I don't know the field name file is attached to? I have page id so I could do $p=$pages->get($id); Now I would need to iterate through Pagefile fields on that page and on each field check if myfile matches. I was hoping for more elegant solution...

Link to comment
Share on other sites

4 hours ago, matjazp said:

It would work, but then I would need existing page

Could you create a dummy page object with $dummyPage = new Page() and use that with new Pagefiles($dummyPage)

 

3 hours ago, matjazp said:

how to get Pagefile object if I don't know the field name file is attached to

Are you working with a hook here, perhaps InputfieldFile::fileAdded ?

If so, you can get the field the file is attached to with $event->object->field

If that's not helpful, maybe give us a little more context.

Link to comment
Share on other sites

4 hours ago, adrian said:

Could you create a dummy page object with $dummyPage = new Page() and use that with new Pagefiles($dummyPage)

Nope, tried that before, page object need to be saved first..

4 hours ago, adrian said:

Are you working with a hook here, perhaps InputfieldFile::fileAdded ?

Not this time, I'm in hook, but with markup only.

4 hours ago, adrian said:

If that's not helpful, maybe give us a little more context.

I just believed that a function/method like

$myfileobject = WiregetPagefile('/site/assets/files/1234/myfile.txt');
or
$myfileobject = $page->getPagefile('/site/assets/files/1234/myfile.txt');

exist somewhere in the core or in core module.

Link to comment
Share on other sites

Take a look at what I did here:

https://github.com/adrianbj/AutoContent/blob/24ec931771d8e80f1e2b7fbd57bd774fedbddd0f/AutoContent.module#L305-L307

$pageimages = $this->getBlankValue($p, $field);
$this->fakerImage = new Pageimage($pageimages, $imagePath);

which makes use of this:

protected function getBlankValue(Page $p, Field $field) {
    $pageimages = new Pageimages($p);
    $pageimages->setField($field);
    $pageimages->setTrackChanges(true);
    return $pageimages;
}

Obviously a bit of a hack, but it seems to work fine. Not sure if this would work for your needs or not.

You will of course need a $field object for file/image field.

EDIT: Sorry, that still needs a page: $p - I didn't notice that when I posted.

  • Like 1
Link to comment
Share on other sites

    function getPageimage ($filename) {

	$f = str_replace(wire('config')->urls->files, '', $filename);
	$id = explode("/", $f)[0];
        
        // get image field types
        $img = new Field();
        $img->type = wire("modules")->get("FieldtypeImage");
        $fieldtypes = $img->type->getCompatibleFieldtypes($img)->getItems();
        unset($fieldtypes["FieldtypeFile"]);
        $selector = "type=" . implode("|", array_keys($fieldtypes));
        
        foreach (wire('fields')->find($selector) as $field) {
            foreach (wire('pages')->find("$field>0, include=all") as $page) {
                $images = $page->getUnformatted($field->name);
                $pageimage = $images[basename($filename)];
		// check should be performed that this image actually reside on the right page
                if($pageimage !== false) {
			if($page->id == $id) return $pageimage; // we have a match
            	}
        }
        
        return null; // no match
        
    }
    
    var_dump(getPageimage('/site/assets/files/1087/img18.jpg')); // Pageimage object
    var_dump(getPageimage('/site/assets/files/1087/nonexistant.jpg')); // null

EDIT: I should grab id from filename and search for image fields on that page only... I could also find image fieldtypes on the page itself...

Link to comment
Share on other sites

I'm after InputfieldFile::renderItem where $event->return is markup. I've updated the function so it works for Pageimage and Pagefile:

    /**
     * Returns Pageimage or Pagefile object from file path
     * getPageimageOrPagefileFromPath('/site/assets/files/1234/file.jpg'); // returns either Pageimage or Pagefile object
     * getPageimageOrPagefileFromPath('/site/assets/files/1234/file.txt'); // returns Pagefile object
     * getPageimageOrPagefileFromPath('/site/assets/files/1234/none.txt'); // returns null
     *
     * @param straing $filename full path to the file eg. /site/assets/files/1234/file.jpg
     * @param Page|null $page if null, page will be contructed based on id present in the file path
     * @return Pagefile|Pageimage|null
     *
     */
    function getPageimageOrPagefileFromPath($filename, $page = null) {

        if(is_null($page)) {
            $id = (int) explode('/', str_replace(wire('config')->urls->files, '', $filename))[0];
            $page = wire('pages')->get($id);
        }

        if(!$page->id) return null; // throw new WireException('Invalid page id');

        $basename = basename($filename);

        // get file field types, that includes image file type
        $field = new Field();
        $field->type = wire('modules')->get('FieldtypeFile');
        $fieldtypes = $field->type->getCompatibleFieldtypes($field)->getItems();
        $selector = 'type=' . implode('|', array_keys($fieldtypes));

        //foreach(wire('fields')->find($selector) as $field) {
        foreach($page->fields->find($selector) as $field) {

            $files = $page->getUnformatted($field->name);
            if($files) {
                $file = $files[$basename];
                if($file) return $file; // match found, return Pagefile or Pageimage

                //check for image variations
                foreach($files as $file) {
                    //if(method_exists($file, "getVariations")) {
                    if($file instanceof Pageimage) {
                        $variation = $file->getVariations()->get($basename);
                        if($variation) return $variation; // match found, return Pageimage
                    }
                }
            }
        }

        return null; // no match

    }

 

  • Like 1
Link to comment
Share on other sites

6 hours ago, matjazp said:

I'm after InputfieldFile::renderItem where $event->return is markup.

You have more than the event->return available to you in the hook - you have $event->object, which is the inputfield.

$this->addHookAfter('InputfieldFile::renderItem', function($event) {
    $inputfield = $event->object;
    $files = $inputfield->value;
    // find file you want in $files
});

 

  • Like 2
Link to comment
Share on other sites

8 hours ago, Robin S said:

You have more than the event->return available to you in the hook - you have $event->object, which is the inputfield

Oh! End $event->arguments[0] being the current rendered file ... Cute :-) Thx for the hint!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...