Jump to content

kixe

Members
  • Posts

    807
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by kixe

  1. If a user is succesfully loggedin in another instance you can force login in the current (only if the user name matches) – no password required. Checkout the code I posted: and add this: $xy->users->setCurrentUser($_user); // search for this wire('session')->forceLogin($_user->name); // add this I would assign profile-edit permission only in the main instance. All this needs a bit coding experience. Be careful and don't create security holes!
  2. I can provide a module for this usecase: https://github.com/kixe/AdminHidePageTreeByRole ... or try one of them: https://processwire.com/modules/admin-restrict-page-tree/ https://processwire.com/modules/admin-restrict-branch/
  3. You can use multiple instances of processwire and include one in another. $pwComments = new ProcessWire($config->paths->root . 'site-comments'); $home = $pages->get(1); $homeOfComments = $pwComments->pages->get(1); https://processwire.com/docs/more/multi-site-support/ use Option #1 https://processwire.com/blog/posts/multi-instance-pw3/#using-multi-instance-in-pw3 This is also possible under a single domain if you do not need a frontend at one of the two installations and use different names for your /admin/ pages and session cookies. Under special circumstances you can also access the current user of one instance within the other. Look here: https://github.com/processwire/processwire-issues/issues/1294#issuecomment-759351593
  4. It's not exactly what you're asking for, but it could be helpful or a first approach to solve your problem: In a ProcessWire multi-instance environment, I needed to get the logged-in user of the central PW instance in all the others and found the following solution. Requires to use different session cookie names in each installation and SessionHandlerDB installed. $config->sessionName = wire0; $config->sessionName = wire1; https://github.com/processwire/processwire-issues/issues/1294#issuecomment-759351593
  5. /** * 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
  6. Thanks. fixed.
  7. 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); } } } } }
  8. 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;});
  9. // '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?
  10. 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?
  11. 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; });
  12. try // ... $results->setStart(6); // index = 7 - 1 $pagination = $pager->render($results);
  13. 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); });
  14. 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; }
  15. 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
  16. @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. ?
  17. 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.
  18. 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
  19. @fruid never touch the core (wire folder). If you need another Uikit version for the frontend. Install in your site/template folder.
  20. If minimum one field is present in the template the other field should be created/ added. No need to go on with the loop.
  21. 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 }
  22. 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]);
  23. 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> "; }
  24. 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) {}
  25. @r.loeber Welcome to the forum. This can be implemented with https://modules.processwire.com/modules/fieldtype-select-ext-option/
×
×
  • Create New...