Jump to content

kixe

Members
  • Posts

    803
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by kixe

  1. /** * allowed flag constants (bitmask) for context * @see core/field.php * */ Field::flagAccess // 32 Field::flagAccessAPI // 64 Field::flagAccessEditor // 128 /** * set context via fieldgroup * @see core/fieldgroup.php * */ $fieldGroup->setFieldContextArray($field_title->id, ['flagsAdd' => 192, 'flagsDel' => 32]); $fieldGroup->saveContext(); /** * set context via fields * @see core/fields.php * */ $field_title = wire('fields')->get('title'); $field_title->addFlag(128); // runtime wire('fields')->saveFieldgroupContext($field_title, $fieldGroup); not tested, but should work
  2. Possible solution to set $user using a setup with multiple sites (multiple databases Option #1), module SessionHandlerDB and different session names for each instance. Put this code in your ready.php $xy = new ProcessWire($config->paths->root . 'site-xy/'); /** * if a session AND a challenge cookie is present we check if the user is still loggedin in xy * if yes we set the @var wire('user') to the xy instance * */ if ($xy->session->hasCookie() && $xy->session->hasCookie(true)) { // get xy session ID if ($xy>config->https && $xy->config->sessionCookieSecure) { $cn = $xy->config->sessionNameSecure; if (!$cn) $cn = $xy->config->sessionName . 's'; } else { $cn = $xy->config->sessionName; } $SID = $input->cookie->$cn; // set the wire('user') if loggedin if ($SID) { $SHDB = $xy->modules->getModule('SessionHandlerDB', array('noPermissionCheck' => true))->getSessionData($SID); if ($SHDB['user_id'] != 40) { // get fingerprint and session timestamp $fp = isset($SHDB['data']['Session']['_user']['fingerprint'])? $SHDB['data']['Session']['_user']['fingerprint'] : false; $ts = isset($SHDB['data']['Session']['_user']['ts'])? (int) $SHDB['data']['Session']['_user']['ts'] : 0; // validate fingerprint if ($xy->session->getFingerprint() !== $fp) { $this->session->error(__('Unable to assign XY user. XY-Session fingerprint does not match.'), Notice::debug | Notice::log); } // check if session timed out else if ($xy->config->sessionExpireSeconds && $ts < (time() - $xy->config->sessionExpireSeconds)) { $this->session->error(__('Unable to assign XY user. XY-Session timed out.'), Notice::debug | Notice::log); } else { $_user = $xy->users->get($SHDB['user_id']); if ($_user->id) { // session valid, assign user & user_id will be set correctly in DB via SessionHandlerDB::write() $xy->users->setCurrentUser($_user); } } } } }
  3. or simply ... $s = $modules->get('SessionHandlerDB')->getSessions(); // seconds = 300, limit = 100 $online_user_ids = array_filter(array_column($s,'user_id'), function($id) {return $id != 40;}); // with all arguments $seconds = 86400; // one day $limit = 200; $s = $modules->get('SessionHandlerDB')->getSessions($seconds, $limit); $online_user_ids = array_filter(array_column($s,'user_id'), function($id) {return $id != 40;}); Unfortunately this doesn't work if ProcessWire is bootstrapped https://github.com/processwire/processwire-issues/issues/1294#issuecomment-748057420 I have to correct myself. It works also if ProcessWire instance is bootstrapped $otherPwInstance = new ProcessWire($config->paths->root . 'site/'); $s = $otherPwInstance->modules->getModule('SessionHandlerDB', array('noPermissionCheck' => true))->getSessions(); $online_user_ids = array_filter(array_column($s,'user_id'), function($id) {return $id != 40;});
  4. // 'include=all' includes access restricted pages, check access via function viewable() before using render() foreach ($page->children('include=all') as $p) { if ($p->viewable()) $p->render(); } // without argument (selector) access restricted pages are excluded by default foreach ($page->children() as $p) { $p->render(); } Why do you want to render multiple pages?
  5. I have 2 ProcessWire instances running under the same domain, each with own session name and cookie. $config->sessionName = 'wire0'; $config->sessionName = 'wire1'; The assignment of the correct instance via url is done in index.config.php. One of the 2 instances is without frontend and accessible only under the related admin url. In this instance (wire0) the user with ID=14179 is logged in. If I check if the session of the related user in this instance is valid I get false. The user var returns unexpected results as well. $xy = new ProcessWire($config->paths->root . 'site-xy/'); var_dump($xy->session->isValidSession(14179)); // false, should be true var_dump($xy->user->isLoggedin()); // false, should be true If I use the $pages, the $users, $config or any other API of the $xy instance I get what I expect. $userIDs = $xy->users->findIDs('check_access=0'); var_dump(count($userIDs)); // correct number of users in related instance var_dump($xy->config->sessionName); // wire0 var_dump($config->sessionName); // wire1 How can I get the $user or $session vars of another PW instance?
  6. I think you don't need a workaround with a hidden field if you do the hook after and change the PageArray instead of the selector. $wire->addHookAfter('ProcessPageList::find', function($e) { $pages = $e->return; if ($pages->first()->parent->id != 111111) return; // quick exit if parent doesn't match $zeroDatePages = $pages->find("date=''"); // empty date pages $result = $pages->filter('date>0,sort=-date'); // pages with date, sort descending $result->prepend($zeroDatePages); // prepend empty date pages $e->return = $result; });
  7. try // ... $results->setStart(6); // index = 7 - 1 $pagination = $pager->render($results);
  8. I use a hook for something similar /** CUSTOM PAGE SORT * related for InputfieldPageListSelect, ProcessPageList (Page tree) * */ $wire->addHookBefore('ProcessPageList::find', function($e) { $parent = $e->arguments(1); $selectorString = $e->arguments(0); // modify $selectorString, remove, modify, add ',sort= ...' $e->arguments(0, $selectorString); });
  9. Do not overwrite the field object (loop item) with the field value. Try: foreach ($page->fields as $field) { $fieldValue = ''; foreach($languageFallback as $languageID) { $fieldValue = $page->getLanguageValue($languageID, $field); if ($fieldValue) break; } $page->$field = $fieldValue; }
  10. Example with 'body' field. Define a language fallback order in ready.php and render first match in template. (not tested ... ) // in ready.php $languageFallback = [1046,1042,1033]; // array of Language-IDs in fallback order $body = ''; $pageActiveLanguageIds = $page->getLanguages()->each('id'); $languageFallback = array_intersect($languageFallback, $pageActiveLanguageIds); foreach($languageFallback as $languageID) { $body = $page->getLanguageValue($languageID, 'body'); if ($body) break; } $page->body = $body; // in your template file echo $page->body; // render field body
  11. @LostKobrakai If the thread doesn't reveal any ListerPro secrets and provide interesting informations about FieldtypeSelector/ InputfieldSelector, it could be moved and made available to everybody, since FieldtypeSelector is not Pro. ?
  12. https://processwire.com/talk/topic/13116-or-selecters-for-different-fields/ Unfortunately the thread is not accessible for everybody. Why? ... which could be found here: https://github.com/processwire/processwire-requests/issues/317 For everyone who is interested in this function. Please vote or add a comment.
  13. Nearly nothing. Displays a warning in the backend and "HTML Markup Quality Assurance" displays a message in debug mode when sleepLinks() detects an absolute URL in a textarea field that does not refer to an allowed host. However, you can add functionality to check the current host. $this->wire('config')->httpHost https://processwire.com/api/ref/config/#pwapi-methods-HTTP-and-input https://processwire.com/docs/start/variables/config/#httphosts
  14. @fruid never touch the core (wire folder). If you need another Uikit version for the frontend. Install in your site/template folder.
  15. If minimum one field is present in the template the other field should be created/ added. No need to go on with the loop.
  16. Small remarks. You should break the loop when work is done: foreach ($page->fields as $field) { if ( $field->type instanceof FieldtypePageTableExtendedGrid ) { // ... break; } } Another approach without loop. Fields is an instance of WireSaveableItems providing a find($selector) function: $selector = implode('|',$fields->find('type=FieldtypePageTableExtendedGrid')->each('name')); if ($page->hasField($selector)) { // ... do something }
  17. The output of the path history on the settings-tab is only visible to superusers. However, you can access the path history of a page through the API. The module has no access restrictions. You may want to output the information somewhere else. $modules->get('PagePathHistory')->getPathHistory($page); Just in case, if you need to access a module with access restriction: $modules->getModule('ModuleWithRequiredPermission', ['noPermissionCheck' => true]);
  18. Maybe useful for you @teppo. In one of my last projects I integrated a lightbox gallery that outputs both videos and pictures. The data source for the videos and images was a PageFile field. Here is an excerpt from the template in which the gallery was integrated via Javascript. Resizing works similarly as suggested by @Robin S // galleries $page->_galleriesJS = ''; $galleriePages = $pages->find('template=gallery'); // 16:9 inline video $markup = '<div class="mfp-video-wrapper"><div class="mfp-video-inner"><video width="854" height="480" controls autoplay preload> <source src="{src}" type="video/mp4"> Leider wird dieses Video von ihrem Browser nicht unterstützt. </video></div></div>'; if ($galleriePages->count) { $galleries = ''; foreach ($galleriePages as $gp) { if ($gp->files->count == 0) continue; $items = []; $filesDirPath = $gp->files->path; foreach ($gp->files as $gi) { if (!fileExists($gi->url)) continue; // inline video if (in_array($gi->ext, array('mp4','m4v','ogg','ogv','mpg'))) { $src = str_replace('{src}', $gi->url, $markup); $items[] = ['type' => 'inline', 'src' => $src]; } // wrong file type else if (!in_array($gi->ext, array('png','jpg','jpeg'))) throw new WireException("Unallowed Fileformat $gi->ext for magnificPopup Gallery"); // any image with youtube video source in description else if (strpos($gi->description, 'youtube')) { $oembed = getVideo($gi->description); if ($oembed) { // nocookie source used $items[] = ['type' => 'iframe', 'src' => $oembed->frameUrl]; } } // image else { $src = $gi->url; $copyFileName = strstr($gi->filename, $gi->ext, true) . '1200x0.' . $gi->ext; list($width, $height) = getimagesize($gi->filename); if ($width > 1200) { if (!file_exists($copyFileName)) { $files->copy($gi->filename, $copyFileName, ['limitPath' => true]); $imageSizer = new ImageSizer($copyFileName); $imageSizer->resize(1200, 0); } $src = str_replace($config->paths->root, '', $copyFileName); } $items[] = ['title' => $gi->description, 'src' => $src]; } } $gallery = [ 'gallery' => ['enabled' => true], 'type' => 'image', 'midClick' => true, 'mainClass' => 'mfp-lightbox-wrapper', 'items' => $items, 'tClose' => 'Schließen (esc)' ]; $gallery = json_encode($gallery); $galleries .= "$('.mfp-open-$gp->id').magnificPopup({$gallery})\n"; } $page->_galleriesJS = "<script> $galleries</script> "; }
  19. Do not use global unless you really know what you are doing. Read this: https://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and $this->wire() is another option to assign global vars, especially for more complex stuff ... like class instances. /** * Get an API variable, create an API variable, or inject dependencies. * * * @param string|object $name Name of API variable to retrieve, set, or omit to retrieve the master ProcessWire object. * @param null|mixed $value Value to set if using this as a setter, otherwise omit. * @param bool $lock When using as a setter, specify true if you want to lock the value from future changes (default=false). * @return object|string|mixed * @throws WireException * * */ public function wire($name = '', $value = null, $lock = false) {}
  20. @r.loeber Welcome to the forum. This can be implemented with https://modules.processwire.com/modules/fieldtype-select-ext-option/
  21. @Patrik97 Welcome to the forum. RepeaterPageArray object represents the value of a repeater field, related to the page where the repeater lives in. A single item of this PageArray is an instance of class RepeaterPage. The class is set via FieldtypeRepeater::getPageClass(). This value is not changeable, the function not hookable. If you want to use a custom class for your repeater item objects with additional methods or properties, you need to create your own Fieldtype, derived from FieldtypeRepeater which includes your custom class and overwrites the getPageClass() function. Example where exactly this is done: FieldtypeRepeaterMatrix Maybe related: https://processwire.com/docs/tutorials/using-custom-page-types-in-processwire/ https://processwire.com/blog/posts/pw-3.0.152/#new-ability-to-specify-custom-page-classes https://processwire.com/talk/topic/20593-pageclasses-and-php-classes/
  22. ? Yet another runtime field. I can also provide one: slim and full PW-API provided. In addition, you can change everything in another field (Database) via hook into ProcessInput. https://github.com/kixe/FieldtypeMarkup
  23. // example 1: modify page title (runtime) for a specific template in Page Edit Interface $this->addHookBefore('ProcessPageEdit::execute', function($e) { $id = wire('input')->get->id; if (!$id) return; $page = wire('pages')->get($id); if ($page->template != 'specific') return; $page->title = "I am a runtime title for pages using template 'specific'"; }); // example 2: modify fields in Profile $this->addHookBefore('ProcessProfile::execute', function($e) { // not for superuser if (wire('user')->isSuperuser()) return; // the user should check 2 checkboxes in its profile // after checking and saving the related checkbox disappears // if both are checked a markup field 'info' is shown $profileFields = $e->object->profileFields; if (wire('user')->checkbox && wire('user')->checkbox_2) $profileFields[] = 'info'; else { if (wire('user')->checkbox != 1) $profileFields[] = 'checkbox'; if (wire('user')->checkbox_2 != 1) $profileFields[] = 'checkbox_2'; } // update profile fields $e->object->profileFields = array_unique($profileFields); });
  24. Please check status and/ or permission $events = $pages->find("template=event, related_pages.template.name=exhibition,include=all,check_access=0"); include=hidden include=unpublished include=all Check if your template is accessible via API if it is not viewable for the current user!
×
×
  • Create New...