-
Posts
2,769 -
Joined
-
Last visited
-
Days Won
31
Martijn Geerts last won the day on December 16 2016
Martijn Geerts had the most liked content!
About Martijn Geerts
- Birthday 02/23/1977
Profile Information
-
Gender
Male
-
Location
The Netherlands
Martijn Geerts's Achievements
-
Hi Marc, I quit my job as developer. I really wanted to work in the outside air and with my hands again. I'm building garden sheds these days and I love it. Maybe someone wil take over some modules I made in the past.
-
Martijn Geerts changed their profile photo
-
Type Page, Selectable pages: Pages you select
Martijn Geerts replied to Martijn Geerts's topic in Wishlist & Roadmap
You sneaky ;-), using 'Selector string' for it ! Love it, should be Core ! -
When configuring a field with type Page there are several ways you can get the "selectable pages". Parent Template Custom find... Selector string Custom PHP code I wish there was an other option: • Pages you select What it should do: Present a pages tree (or autocomplete) Allow selecting multiple pages The pages you have selected, are the options in this field.
-
@Macrura First of all I love SettingsFactory! I've seen notices before in SettingsFactory when I add new fields but not yet saved the value. In this complicated setup I have here this notice prevents the PageList from being loaded. SettingFactory->getSettings() triggers the notice on line 152. // Locally i have changed the if statemaent on line 151: } else { $newDataArray[$key] = $dataArray[$key]; } // To this: } else if (isset($dataArray[$key])) { $newDataArray[$key] = $dataArray[$key]; } Without looking much in to this, this fixes it for me.
-
Selector vs direct database search efficiency
Martijn Geerts replied to Hurme's topic in API & Templates
When requesting a page with selector you do not request other fields exept title as it is set to autojoin. -
https://processwire.com/api/ref/page/save/
-
yep I see, looks like PagePermissions::userEditable() returns false. First of all, I don't see the whole context of the repeater page thing in ProcessCroppableImage4->___execute(), I also think the solution in there doesn't work when you have nested repeaters. In ProcessCroppableImage4->___execute(), you are checking for $page->editable(). In case of the user profile $page === $this->wire('user') This is what I think: /** * Is the Page|Page->field editable? * * @param integer $pages_id * @param string $field * @return boolean * @throws WireExeption When not ediable */ private function isEditable($pages_id = 0, $field = '') { $editable = false; /** @var Pages $pages */ $pages = $this->wire("pages"); /** @var User $user */ $user = $this->wire("user"); /** @var User $user */ $user = $this->wire("user"); /** @var integer $pages_id, Page Id from page being edited */ $pages_id = (int) $pages_id; /** @var string $field, Croppable image fieldname */ $field = strval($field); if (!$pages_id || !$field) return $editable; /** @var Page|NullPage */ $page = $pages->get($pages_id); if ($page instanceof RepeaterPage) { while (!($page instanceof RepeaterPage)) { $page = $page->getForPage(); } } if (!($page instanceof Page)) throw new WireException("Not a valid page"); if (!$page->id) throw new WireException("Not a valid page"); // Set Page to WireData $this->set("page", $page); // Returns false for user template in: PagePermissions::userEditable() $editable = $page->editable(); // We need to check if the field is also editable from Page context. if ($editable) $editable = $page->editable($field); // When comming from ProcessProfile, the $page === $this->wire('user') if (!$editable && $page === $user) { // User must have profile `profile-edit` permission $editable = $user->hasPermission("profile-edit"); if ($editable) { $pagePermissions = $this->wire("modules")->get("PagePermissions"); // Is the field actually in the profile? $editable = $pagePermissions->userFieldEditable($field, $user); } } return $editable; } // then in ProcessCroppableImage4::___execute() { public function ___execute() { //$this->config->scripts->add($this->config->urls->ProcessCroppableImage4 . "scripts/Jcrop/js/jquery.color.0-9-13.js"); $this->config->scripts->add($this->config->urls->ProcessCroppableImage4 . "scripts/Jcrop/js/jquery.Jcrop.min.0-9-13.js"); $this->config->styles->add($this->config->urls->ProcessCroppableImage4 . "scripts/Jcrop/css/jquery.Jcrop.min.0-9-13.css"); $this->config->scripts->add($this->config->urls->ProcessCroppableImage4 . "scripts/ProcessCroppableImage4.js"); $this->config->styles->add($this->config->urls->ProcessCroppableImage4 . "styles/ProcessCroppableImage4.css"); $this->wire('processHeadline', 'Croppable Image 4'); $field = $this->sanitizer->fieldName($this->input->get->field); if(preg_match("/_repeater[0-9]+$/", $field)) { $pages_id = (int) end((explode("_repeater", $field))); $field = str_replace("_repeater$pages_id", "", $field); } else { $pages_id = (int) $this->input->get->pages_id; } $filename = $this->sanitizer->name($this->input->get->filename); $height = (int) $this->input->get->height; $width = (int) $this->input->get->width; $suffix = $this->sanitizer->name($this->input->get->suffix); if($pages_id < 0 || strlen($filename) < 3) { $out = CroppableImage4Helpers::getTemplate("jcrop", array( 'invalidFieldText' => $this->getText('invalidFieldText') )); return $out->render(); } $editable = $this->isEditable($pages_id, $field); if ($editable) $page = $this->data("page"); if (!$editable) throw new WireExeption("Page not editable"); ...... // In ProcessCroppableImage4::___executeSave() : public function ___executeSave() { /** Checklist: sanitisation and validation of each post param * * [x] - [x] pages_id * [x] - [x] field * [x] - [x] filename * [x] - [x] suffix * [x] - [ ] crop * [x] - [x] targetWidth * [x] - [x] targetHeight * [x] - [x] quality * [x] - [x] sharpening */ // get page-id from post, sanitize, validate page and edit permission $pages_id = intval($this->input->post->pages_id); // $page = wire('pages')->get($pages_id); // if(!$page->id) throw new WireException("Invalid page"); // $editable = $page instanceof RepeaterPage ? $page->getForPage()->editable() : $page->editable(); // if(!$editable) throw new WirePermissionException("Not Editable"); // get fieldname from post, sanitize and validate $field = wire('sanitizer')->fieldName($this->input->post->field); $editable = $this->editable($pages_id, $field); if ($editable) $page = $this->data("page"); if (!$editable) throw new WireExeption("Page not editable"); .....
-
Lister - Session bookmarks for runtime drill-down
Martijn Geerts replied to MarkE's topic in General Support
If I do understand you correctly I have build a Module for this some years ago: https://github.com/Da-Fecto/ProcessPageListerUrls Haven't used it in ages, but maybe it stil works. -
Hi @horst, On top of my head: Add the Croppable image field. (plain install, no update) Configure the field & attach to user template. Allow the field in ProcessProfile. (You should configure it in ProcessProfile) Go to your ProcessProfile and click the thumbnail button you configured. As you can see in the browser input bar when ProcessProfile is open there is no get parameters present in the URL. p.s. I'm open for a telephone call :-).... send you a PM with my mobile number.
-
Hi Horst, Time flies, the oldest on secundary school now and the youngest just had her 6th birthday. Live is sweet. How are you doing?
-
Hi @horst, When using this module from the user profile, the InputfieldCroppableImage4.module cannot get the $pages_id, thus trowing an Exception. With the addition below you can get the $pages_id from the Process running. I did not much testing so I Don't know if it is sufficient. <?>php // added at line 129, InputfieldCroppableImage4.module /** @var integer $pages_id, Page ID for crop links, defaulting to 0 */ $pages_id = 0; /** @var [ProcessPageEdit|ProcessUser|ProcessProfile] $process, Mixed processes maybee there are more */ $process = $this->wire("process"); if (method_exists($process , "getPage")) { $editPage = $process->getPage(); if ($editPage->id) $pages_id = $editPage->id; } $pages_id = $pages_id ? $pages_id : (int) $this->input->get->id; // And I Changed the of pages_id property of the $cropUrlWithParams to the var $pages_id Thanks for being so active.
-
Hi @Ivan Gretsky The code I gonna paste here is a copy/paste from other work so there might be glitches. And you should use your own fieldnames etc. What you can do is: Create a template and template file for RSS name it rss. Template not ending with slash. (Name a the page that uses this template should end with .rss In the template file something like: <?php namespace ProcessWire; use DomDocument; use DOMElement; use DateTime; header('Content-Type: application/xml; charset=utf-8', true); date_default_timezone_set("Europe/Amsterdam"); setlocale(LC_MONETARY, 'nl_NL'); /** @var \DateTime */ $date = new DateTime('today midnight'); $items = $pages->find("YOUR SEARCH SELECTOR DON'T FORGET TO SET LIMIT"); /** * Start XML Object * * @var DOMDocument */ $dom = new DOMDocument("1.0", "UTF-8"); $root = $dom->appendChild($dom->createElement("rss")); $root->setAttribute("version","2.0"); $root->setAttribute("xmlns:dc","http://purl.org/dc/elements/1.1/"); $root->setAttribute("xmlns:content","http://purl.org/rss/1.0/modules/content/"); $root->setAttribute("xmlns:atom","http://www.w3.org/2005/Atom"); $link = $dom->createElement("atom:link"); $link->setAttribute("href", $page->httpUrl()); $link->setAttribute("rel","self"); $link->setAttribute("type","application/rss+xml"); $channel = $root->appendChild($dom->createElement("channel")); $channel->appendChild($link); $channel->appendChild($dom->createElement("title", $page->title)); $channel->appendChild($dom->createElement("description", $page->description)); $channel->appendChild($dom->createElement("link", $page->httpUrl)); $channel->appendChild($dom->createElement("language", "nl")); $channel->appendChild($dom->createElement("lastBuildDate", $date->format(DateTime::RFC2822))); $channel->appendChild($dom->createElement("generator", "DomDocument, ProcessWire")); foreach ($items as $item) { $dateInt = (int) $item->getUnformatted("date_start"); if (!$dateInt) $dateInt = (int) $item->modified; /** @var DateTime $date */ $date = new DateTime(date("Y-m-d", $dateInt)); /** @var DOMElement $parent */ $itemParent = $dom->createElement("item"); // Plain tags $elements = array( $dom->createElement("title", $item->title), $dom->createElement("description", htmlspecialchars($item->description)), $dom->createElement("link", $item->httpUrl()), ); // For closure $image = $images->first(); $image = $image->size(600, round(600 * 9 / 16)); $mime = $image->ext === 'jpg' ? "image/jpeg" : "image/png"; $enclosure = $dom->createElement("enclosure"); $enclosure->setAttribute('url', $image->httpUrl()); $enclosure->setAttribute('type', $mime); $enclosure->setAttribute('length', $image->filesize); $elements[] = $enclosure; foreach ($elements as $element) $itemParent->appendChild($element); $channel->appendChild($itemParent); } echo $dom->saveXML(); When you want to place the RSS in the root you could hide it for non superusers: /** * Hide RSS page * * Hide RSS page int pagelist for NON superusers * */ $wire->addHookBefore("ProcessPageList::find", function (HookEvent $event) { /** @var User $user */ $user = $this->wire("user"); if ($user->isSuperuser()) return; /** @var Page $page */ $page = $event->arguments(1); /** @var string $baseSelector */ $baseSelector = $event->arguments(0); $selector = $baseSelector . ", template!=rss"; $event->arguments(0, $selector); }); Hope this could be a good starting point for you.
-
Have not used it with PW3, now-a-days I use DomDocument
-
How to prevent an admin account from taking over the server?
Martijn Geerts replied to Anders's topic in Security
When you know your I.P. maybe you could check against that. One hook you could use is session::allowLogin -
FieldtypeSelectFile & InputfieldSelectFile
Martijn Geerts replied to Martijn Geerts's topic in Module/Plugin Development
There has been a small update on this module thanks to @Jonathan Lahijani. @Jonathan Lahijani added: PHP files can have a comment called "Description" at the top of the file which will be displayed in the dropdown if it exists. Check this option to disable it.