Jump to content

BitPoet

Members
  • Posts

    1,331
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by BitPoet

  1. Perhaps this small snippet for site/ready.php could be also sufficient (it prepends a dot to the directory name for pages with a given template): <?php wire()->addHookAfter("PagefilesManager::path", null, "protectedpath"); function protectedpath(HookEvent $event) { $page = $event->object->page; if($page->template == 'specialpath') { $event->return = preg_replace('~(\d+/?)$~', '.$1', $event->return); } }
  2. Yes, that. It's been ages since I ran something in such a scenario, but strange session inconsistencies like yours weren't unheard of back then when multiple web server instances shared the same session directory and servers came under heavy load. I never managed to find the exact culprit, but I believe that there were both randomness issues in /dev/(u)random and race conditions in the routines that check whether a session id already exists in the file system.
  3. The find call returns the pages in the order in which they are configured to be sorted. A PageArray keeps the order in which the pages were added (minus duplicates, for which the last addition counts) unless you explicitly call its sort method. There is one exception to the rule, which is when you pass a PageArray to add() or append(). In that case, the items in that PageArray get prepended. I'm not sure if this is intentional.
  4. Some race condition on the server with a shared session directory perhaps? In that case, enabling SessionHandlerDatabase should instantly get rid of the problem. Looking closer, two of the three IPs in the log belong to cloudflare, so if you're using their CDN to speed up the site, this could be a misconfiguration there too. Is the backend routed through Cloudflare? Could it be that there's an option to preserve cookies active? I've got no experience with Cloudflare, but I have seen some very dangerous options to that extent available with Akamai.
  5. In PW's multi-language handling for text-based fields, these fields don't hold a regular string (as they do in non-ml setups) but a LanguagesPageFieldValue object. This object stores the field values (strings) for the different languages. When you retrieve the string value of such a field, PHP's standard magic calls _toString on the object. The implementation for _toString is done in the hookable getStringValue method. Unfortunately, while the LanguagesPageFieldValue objects do know their page and field, the information isn't accessible from a hook. But you can always access $this->wire('page') to get the current page in the frontend. Then you can retrieve the absender through $page->absender->first(). Some quick&dirty code for the function that probably illustrates this better (the above sounds more complicated than it really is): /* ... */ $mlObj = $event->object; // LanguagesPageFieldValue object $currPage = $this->wire('page'); if($currPage->template == "doctors") { $absender = $currPage->absender->first(); $absLang = $absender->sprache; $event->return = $mlObj->getLanguageValue($sprache); } /* ... */ As long as you apply use this logic to all language fields on a template, this approach should work fine. Otherwise, it would probably get complicated.
  6. You have to hook LanguagesPageFieldValue::getStringValue, adding your own logic there and retrieving the values using $event->object->getLanguageValue($language). You could set the default language to use in a page field (template=language) added to the user template.
  7. Add this line somewhere before the RewriteRule directive in Point 19. RewriteCond %{REQUEST_URI} !^/?wordpress(/.*)?$ This pattern tells the rewrite engine to look for the following in the requested URI: ! = negation, this rule succeeds if the match fails ^ = start at beginning of the string /? = look for an optional forward slash followed by the word "wordpress" (/.*)? = optionally followed by a forward slash and arbitrary characters $ = match until the end of the string
  8. Of course. You only have to exclude the wordpress folder from URL rewriting in .htaccess.
  9. OR-groups should do the trick. template=entrytpl, (parent.id=7077), (id=7077), sort=relatedstuff.release_date, sort=someotehrfield, start=0, limit=100
  10. When you're on a development system, enable display_errors and html_errors and set error_reporting to E_ALL in php.ini. This way, you'll get a sensible output for most errors. If you still end up with an internal server error and your http server's error log isn't cluing you in, you can try bootstrapping PW from the command line and rendering the page that causes the error from there. <?php // Needs to reside in PW's main directory where index.php is, otherwise // the path to index.php needs to be passed to include(). include('index.php'); echo $pages->get('/your/faulty/page/')->render(); In your example, you use the Page::render function. Admittedly, it's a bit unfortunate that there isn't a more detailed description linked in the 3.x API docs for $page/Page. The (optional) first argument to that function is either the name of a field on the page (in which case it searches for a field template with a matching name) or the name / path (relative to the templates directory) of the PHP template to use. The '/' you pass here apparently doesn't do what you think. <?php $contact = $pages->get('/contact/'); /* retrieve contact page*/ // Renders output using the template file assigned in the backend // that $contact uses: $contactRendered = $contact->render(); // Or: use a different PHP file than the template's default, // relative to site/templates. This call will look for a PHP // template site/templates/contact_simple.php $contactRendered = $contact->render('contact_simple.php'); echo $contactRendered; /* output rendered contact page here */ ?> One little thing that makes development infinitely easier in the long run is to always be as explicit as possible when you name your variables. Try to avoid generic names like $getPages (unless you're really writing a generic function that deals with all kinds of pages), make them descriptive about what they contain and let singular and plurals forms tell you whether they hold a single instance or multiple. I've adapted the snippet of code accordingly.
  11. Another possible approach would be to add the condition in the head of the calculator template file, include the result template when met and return, otherwise proceed as normal. calculator.php: <?php if($input->get->firstvalue && $input->get->secondvalue ) { include('_result.php'); return; } ?> /* The regular calculator template follows here */ This way, you don't have any "strange magic" that swaps templates and that you'll have to search for when you re-visit the code in three years time
  12. You've already understood that $page is always the current page. To output contents of another page, you have to retrieve that page first and store it into a variable. You can do that with $pages->get(). <?php $page1 = $pages->get('/page1/'); /* must be the path to your page from home, e.g. simply '/' if you want to retrieve the home page itself */ ?> <section> <h1><?= $page1->title ?></h1> <p><?= $page1->summary ?> <br> <?= $page1->message ?> </p> </section> As always, there are multiple ways to make things easier and more intuitive in PW, depending on the exact requirement. One important thing to understand about ProcessWire is that you store content in pages but define both structure and output in templates (forgive me if I'm being overly verbose here. I always try to point things out in detail for others stumbling upon a forum page later on with a similar question in mind). In most cases, you'll have multiple pages with the same template, and what additional content you want to show depends on the template. You may have a page 5, page 12 and page 34 that are similar and all need to include content from page 1 - in that case, you can give them all the same template and hard-code page 1 in the template like I did above. Or they all need to include content from another page, but that page varies. Instead of defining a different template for each one, you add a page field to their template definition, choose the page to include in the page editor and, instead of retrieving a page explicitly, you simply use the properties of the page field as it will be a full-fledged page object. <section> <h1><?= $page->yourpagefield->title ?></h1> <p><?= $page->yourpagefield->summary ?> <br> <?= $page->yourpagefield->message ?> </p> </section> You can even go one step further and define your own PHP template for outputting a page's contents in a different context. There's a forum thread with good points and examples illustrating different ways of page and field rendering and the use of wireRenderFile. These open up tons of possibilities to organize your template structure, even allowing you to build flexible widget systems with very little code.
  13. The compiler, unfortunately, isn't really picky about things. It touches keywords like "require" and "include" inside and outside of the "real" PHP code, including comments. So, the quick solution would be to load hljs the classic way (<script src=...>).
  14. Ah, should have looked more closely. Try this: $result = wireZipFile($zipfile, $foldertozip, array( 'exclude' => array( basename($config->paths->templates) . '/errors') ));
  15. @flydev: The code in your first post needs to assign an array to the exclude option: $result = wireZipFile($zipfile, $foldertozip, array( 'exclude' => array( $config->paths->templates.'errors') )); From a quick glance at ProcessExportProfile, it looks like $dir is a relative path.
  16. It appears that the last commits were quite incomplete, though the newer versions on my dev drive also had a few issues of their own. That's what you get when you replace sleeping with coding once too often I've updated both client and server module to 0.0.7 now, with partially re-written handshaking logic and a more detailed remote module list feature. I'll be quite busy the rest of the week (including the weekend), but if time allows, I want to tackle two issues in the first half of November: a cryptographic handshake - don't like really plaintext passwords going over the wire - and a documentation and an example module for the remote actions system. The latter will no bring up some more issues that needs fixing/tweaking along the way. My priority will be on my DatetimeAdvanced and JsonNativeField modules though, as I'll be using these in a production system in the near future, so I wouldn't ask anybody to hold their breath yet.
  17. Your description is a bit hard to understand without a visual overview, but my suspicion (correct me if I'm wrong) is that you're building one complete form on the parent page from all child (question) pages. This would mean that the if($input->post->submit) part is executed in each included template every time you submit the form.
  18. Mac OS' file system HFS+ is by default case insensitive, which means that it doesn't matter if you mix upper- and lowercase paths and filenames. Telling your editor software to open /somefolder/somefile.php and /SomeFolder/SOMEFILE.php will bring up the same file. When you format a partition on Mac OS, you can choose to make the file system case sensitive instead, thus you can have somefile.php and SOMEFILE.php in the same folder. There's a PHP bug already showing the same issue outside of ProcessWire. You might vote that up to get it more attention. One other idea that came to mind: check if opcache is enabled in php.ini (I think MAMP still does this by default and its been known to cause strange problems). If yes, setting opcache.enabled to 0 and restarting MAMP might be worth a shot. (And don't trust what the the "cache" option in the GUI.)
  19. Have you tried a different PHP version? There's been some shuffling around with which system calls PHP uses for file access, so it might be that a different version produces different results. Otherwise, moving MAMP and PW to a case sensitive partition might also be an option (MAMP and PW are on the same partition, right?).
  20. I can't help but suspect that the issue may be caused by a snippet of module code you haven't shown us yet.
  21. A cheap rip-off of LanguageSupportPageNames that adds support for prefixed urls, localUrl and localHttpUrl: <?php /** * Adds simple support for URL paths prefixed by language name. * * Proof-of-concept. * * Most of the actual code is stolen from LanguageSupportPageNames. * Adds the same localUrl and localHttpUrl methods to page objects. * */ class LanguageSupportPath extends Wire implements Module { public static function getModuleInfo() { return array( "title" => __("Support for Language Path"), "summary" => __("Adds simple support for URL paths prefixed by language name"), "version" => "0.0.3", "autoload" => true, "requires" => array( "LanguageSupport" ) ); } public function init() { $this->addHookBefore("ProcessPageView::execute", $this, "hookProcessPageViewExecute"); } public function ready() { $this->addHook('Page::localUrl', $this, 'hookPageLocalUrl'); $this->addHook('Page::localHttpUrl', $this, 'hookPageLocalHttpUrl'); } /** * Hook in before ProcesssPageView::execute to capture and modify $_GET[it] as needed * */ public function hookProcessPageViewExecute(HookEvent $event) { $event->object->setDelayRedirects(true); // save now, since ProcessPageView removes $_GET['it'] when it executes $it = isset($_GET['it']) ? $_GET['it'] : ''; if(!$this->isAssetPath($it)) { if(strpos($it, "processwire/") !== 0) $this->log->message("Original path: $it"); $it = $this->updatePath($it); if(strpos($it, "processwire/") !== 0) $this->log->message("Updated path: $it"); $_GET['it'] = $it; } } /** * Is the given path a site assets path? (i.e. /site/) * * Determines whether this is a path we should attempt to perform any language processing on. * * @param string $path * @return bool * */ protected function isAssetPath($path) { $config = $this->wire('config'); // determine if this is a asset request, for compatibility with pagefileSecure $segments = explode('/', trim($config->urls->assets, '/')); // start with [subdir]/site/assets array_pop($segments); // pop off /assets, reduce to [subdir]/site $sitePath = '/' . implode('/', $segments) . '/'; // combine to [/subdir]/site/ $sitePath = str_replace($config->urls->root, '', $sitePath); // remove possible subdir, reduce to: site/ // if it is a request to assets, then don't attempt to modify it return strpos($path, $sitePath) === 0; } /** * Given a page path, return an updated version that lacks the language segment * * It extracts the language segment and uses that to later set the language * */ public function updatePath($path) { if($path === '/' || !strlen($path)) { $this->user->language = $this->wire('languages')->getDefault(); return $path; } $trailingSlash = substr($path, -1) == '/'; $testPath = trim($path, '/') . '/'; $home = $this->wire('pages')->get(1); $found = false; foreach($this->wire('languages') as $language) { if($language->isDefault()) continue; $name = $language->name . "/"; if(strpos($testPath, $name) === 0) { $found = true; $this->user->language = $language; $path = substr($testPath, strlen($name)); break; } } if(!$found) $this->user->language = $this->wire('languages')->getDefault(); if(!$trailingSlash && $path != '/') $path = rtrim($path, '/'); return $path; } public function hookPageLocalUrl(HookEvent $event) { $lang = $this->getLanguage($event->arguments(0)); $event->return = $this->wire('config')->urls->root . ltrim(($lang->isDefault() ? "" : $lang->name) . $event->object->path, "/"); } public function hookPageLocalHttpUrl(HookEvent $event) { $this->hookPageLocalUrl($event); $url = $event->return; $event->return = $this->wire('input')->scheme() . "://" . $this->wire('config')->httpHost . $url; } /** * Given an object, integer or string, return the Language object instance * * @param int|string|Language * @return Language * */ protected function getLanguage($language) { if(is_object($language)) { if($language instanceof Language) return $language; $language = ''; } if($language && (is_string($language) || is_int($language))) { if(ctype_digit("$language")) $language = (int) $language; else $language = $this->wire('sanitizer')->pageNameUTF8($language); $language = $this->wire("languages")->get($language); } if(!$language || !$language->id || !$language instanceof Language) { $language = $this->wire('languages')->get('default'); } return $language; } public function ___install() { if($this->modules->isInstalled("LanguageSupportPageNames")) { throw new WireException($this->_("LanguageSupportPath and LanguageSupportPageNames cannot be active at the same time")); } } } This way, of course, the page paths after the prefix are identical for all languages, which might not be desired for SEO reasons. The module also may have side effects from setting the language that I didn't consider, so use at your own risk
  22. If you only want to sort in-memory, getting the pages as a plain array and using a custom sort function should do the trick: <?php $ps = $pages->find('yourselector')->getArray(); usort($ps, function($a, $b) { $na = $a->name; $nb = $b->name; if(!ctype_digit($na) && !ctype_digit($nb)) return strcmp($na, $nb); if(ctype_digit($na) && ctype_digit($nb)) return strcmp($na, $nb); return (ctype_digit($na)) ? 1 : -1; }); foreach($ps as $p) echo $p->name . PHP_EOL;
  23. While LanguageSupportPageNames is in fact optional, rolling your own language handling under the hood needs a bit of coding. Basically, you have to implement by yourself what LanguageSupportPageNames does in hookProcessPageViewExecute(), isAssetPath() and updatePath(), that is, intercept the request and, if there's a language prefix in the URL and it's not a request for an asset file, extract the path and language, set the user's language and update $_GET["it"] (the requested URL) with the non-prefixed URL.
  24. @alan: are you talking about images or files, which are two different beasts in PW? For regular files, your memory requirement seems too high, but for images @LostKobrakai's recommendation applies. If we're in fact talking images, you might try a more recent PW version (as far as I remember, there was a fix after 2.7.3 came out that removes in-memory copies earlier when resizing images) and/or have a look at ImageSizerEngineIMagick. Also, if you have $config->debug set to true, it might be worth checking if the memory requirement changes when you disable it.
  25. Looks like you're running PHP 5.3 on the live system. You could fix this error by replacing the short array notation [...] used throughout the module with its verbose notation as array(...), but you should really think of switching to a more current PHP release.
×
×
  • Create New...