matjazp Posted November 21, 2016 Share Posted November 21, 2016 How to create Pagefile or Pageimage knowing only file url, like /site/assets/files/1234/file.txt Link to comment Share on other sites More sharing options...
Robin S Posted November 21, 2016 Share Posted November 21, 2016 $my_files_field->add('/path/to/file.pdf'); Same for Pageimages, which inherits the methods and properties of Pagefiles. https://processwire.com/api/ref/pagefiles/https://processwire.com/api/ref/pagefiles/add/ 1 Link to comment Share on other sites More sharing options...
matjazp Posted November 21, 2016 Author Share Posted November 21, 2016 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 More sharing options...
LostKobrakai Posted November 21, 2016 Share Posted November 21, 2016 Pagefiles are only supposed to exist in the context of a page and a related field, because lot's of it's functionality does depend on information stored in those objects. Link to comment Share on other sites More sharing options...
Robin S Posted November 21, 2016 Share Posted November 21, 2016 The field may not be necessary but I think you'll have to associate the file with a Page (it is called a Pagefile after all). You can do this: $my_files = new Pagefiles($some_page); $my_files->add('/path/to/file.pdf'); 1 Link to comment Share on other sites More sharing options...
matjazp Posted November 21, 2016 Author Share Posted November 21, 2016 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 More sharing options...
adrian Posted November 21, 2016 Share Posted November 21, 2016 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 More sharing options...
matjazp Posted November 21, 2016 Author Share Posted November 21, 2016 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 More sharing options...
adrian Posted November 21, 2016 Share Posted November 21, 2016 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. 1 Link to comment Share on other sites More sharing options...
matjazp Posted November 22, 2016 Author Share Posted November 22, 2016 Yes, you would need a field and a page and I don't have that ... Link to comment Share on other sites More sharing options...
matjazp Posted November 22, 2016 Author Share Posted November 22, 2016 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 More sharing options...
Robin S Posted November 22, 2016 Share Posted November 22, 2016 How is that you have a path to a file (the $filename argument in your function) that exists in a field on a page without any information about the page and field? Where does $filename come from? 2 Link to comment Share on other sites More sharing options...
matjazp Posted November 22, 2016 Author Share Posted November 22, 2016 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 } 1 Link to comment Share on other sites More sharing options...
Robin S Posted November 22, 2016 Share Posted November 22, 2016 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 }); 2 Link to comment Share on other sites More sharing options...
matjazp Posted November 23, 2016 Author Share Posted November 23, 2016 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 More sharing options...
tpr Posted November 23, 2016 Share Posted November 23, 2016 Just use bdl($event) if Tracy is installed and click around 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now