Jump to content

BitPoet

Members
  • Posts

    1,331
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by BitPoet

  1. Something's off here, as 2.7.2's index.php doesn't even have a line 254 (2.7.3 neither, and 3.x' is even shorter). Reid, can you take a look what line 254 in your index.php is?
  2. Try the latest version
  3. I've stumbled over the same behavior a few days ago running PHP 7 and PW version 3.0.15, so it's not limited to either of those.
  4. There's a little bit of trickery involved when adding back a "save unpublished" button for user pages as InputfieldPassword has its own little piece of logic that sets itself to required when processing input for an unpublished page, but here's a quick-n-dirty attempt at a module.
  5. Are you sure you want this? If you do, you'll have to define for yourself what makes a browser a "mobile" device. Nowadays, neither UserAgent-sniffing nor screen resolution or touch feature testing alone are enough as a sorting criterion. Any libraries I've seen out there use a mix of all those, and they need constant updating as browsers change their features and mobile devices grow larger screens. A lot of laptops support touch now too, but you don't want to serve the mobile version to a 4k-displayed ChromeOS notebook just because the browser window doesn't take up the full screen width at the moment it visits your page. I'd call successful separation of regular and mobile devices a science for its complicatedness, but for a science, it's far too imprecise. If you decide to go down that path anyway, there are a number of libraries out there, just googling "Javascript detect mobile browser" gives me quite the list. You'll have to decide yourself which version supports the features you regard as distinctive. I'd then use a JS popup to let the user decide if they want to go mobile or stay on the main site, add mobile/full version links on every page and add another site directory for m.mydomain.com with the mobile templates and auxiliary files.
  6. Sort order isn't really part of the character set, it's decided by the accompanying collation. Currently, PW doesn't set this explicitly, which means it defaults to the default setting of the database (as far as that is applicable to the individual table's character set). Changing the charset to a single-byte one is not advisable nowadays, but you shouldn't need to anyway. Simply set your database's collation to utf8_swedish_ci before you install PW. ALTER DATABASE whateveryounamedit CHARACTER SET utf8 COLLATE utf8_swedish_ci; After that, any newly created tables with utf8 charset follow the Swedish sorting and substitution rules.
  7. Looks like phil is trying to install it on PW 2.x where namespaces aren't supported. Perhaps add a requirement in getModuleInfo for >= 3.0.10 for all those not looking at the module's description? requires => array('ProcessWire>=3.0.10')
  8. I'm still a bit stumped to read that find() on PageArrays works for you. I just tested again on 2.7 and 3.0.16, and in both versions, I don't get any results if try to filter a PageArray by a relative time. To illustrate that: $old = $pages->find("created>='65 days ago'"); // this gives back 8 results $fresh = $pages->find("created>='30 days ago'"); // this gives back 1 result $filtered = $old->find("created>='30 days ago'"); // this gives back an empty PageArray, though getTotal() still returns 8 ()
  9. It's not just about finding in memory vs. finding in the database. Generally, you can only assume that relative timestamps work when you're callling find() on $pages/wire('pages'). In your example, you're calling find() on the comments fieldtype. You're not looking for pages (comments aren't pages but rather entries in a multivalued field, like an extended FieldtypeTextarea). FieldtypeComments::find casts a good number of selector values to integer when assembling the database query: if(in_array($f, array('id', 'status', 'created', 'pages_id', 'parent_id', 'created_users_id', 'upvotes', 'downvotes'))) { $_sql .= "AND $f$operator" . ((int) $value) . " "; Thus, you can assume that relative timestemps work when there's a $pages or wire('pages') (or $this->pages inside a module) in front of your find() call. It probably won't work if you are calling $somepage->somefield->find(), unless somefield is a page field. It won't work if you call it on a PageArray (or other WireArray), so $pages->find(someselector)->find(selector_with_relative_timestamp) will fail. Relative timestamps are hardcoded in core/PageFinder.php to work for "created", "modified" and "published". It would probably be feasible to modify FieldtypeComments::find to employ the same logic: if(in_array($f, array('id', 'status', 'pages_id', 'parent_id', 'created_users_id', 'upvotes', 'downvotes'))) { $_sql .= "AND $f$operator" . ((int) $value) . " "; } else if($f == 'created') { $value = (ctype_digit($value)) ? (int)$value : strtotime($value); $value = date('Y-m-d H:i:s', $value); $_sql .= "AND $f$operator'" . $value . "' "; I've taken the liberty to file a feature request on github.
  10. Just grab the latest version from git (if you get a message that configurable module test failed, repeatedly refresh modules until the message goes away), then go into the module configuration and select "Radios". You can exclude certain media pages from showing up for the user through a hook in ready.php: wire()->addHookAfter("MediaLibrary::getPageMediaLibraries", null, "filterLibraries"); function filterLibraries($event) { $media = $event->return; if(! wire('user')->isSuperUser) { $event->return = array_filter($media, function($v) { return ($v->id != $ID_OF_PAGE_TO_EXCLUDE); }); } }
  11. I'm a little bit uncomfortable with allowing just any child under a media library, but I can understand the wish for nesting, so version 0.0.7 on github allows you to create libraries under existing MediaLibrary pages, and these child libraries (no limit for nesting) are also listed whenever their parent library is. For anybody planning to use MediaLibrary through the API, there's a new method that returns an array with all applicable media pages for a given page (following the under-parent-or-current-page rule): $ml = wire('modules')->get('MediaLibrary'); $mediapages = $ml->getPageMediaLibraries($page); foreach($mediapages as $mpage) { // ... } I've made getPageMediaLibraries hookable if anybody wants to apply further rules to which pages should be available.
  12. It's not really designed to be used in a template through the API, the use case was to make re-using images and documents in CKEditor less complicated. Behind the scene, MediaLibraries are nothing but pages with a MediaImages and MediaFiles field, the magic is the concise overview over dedicated media pages (and their creation without navigating through the page tree) and, most importantly, the quick selection in the CKEditor dialogs. You can get the available libraries for a page through the API though: /* Retrieve all available MediaLibraries for the current page */ // get possible parents first $mparents = $page->parents->and($page); // get PageArray with all possible libraries $libs = $pages->find("template=MediaLibrary, parent=$mparents"); // do something with libraries foreach($libs as $lib) { echo $lib->title . PHP_EOL; // Every library is just a page with the fields MediaImages and MediaFiles foreach($lib->MediaImages as $img) { echo "<img src='$img->url'/><br/>" . PHP_EOL; } } Of course, you can fetch a specific library through regular selector syntax too, e.g.: $lib = $pages->get("template=MediaLibrary, name=global-media"); foreach($lib->MediaFiles as $file) { // ... }
  13. Nothing exotic, just changing title|headline|heading|subhead|lead|body|profile|summary|meta_keywords~=van Meter to title|headline|heading|subhead|lead|body|profile|summary|meta_keywords%=van, title|headline|heading|subhead|lead|body|profile|summary|meta_keywords%=Meter In our PW based intranet, where I use OpenSearchServer to search pages, attachments and external files, I've had the same problem (with a few tweaks due to stemming and synonyms), and after a lot of testing this and that, I compromised on setting minimum word length to three and adding an "exact search" option for those cases where fulltext searching returned too many or too few results. Unfortunately, I haven't found the perfect, intuitive find-it-all solution yet
  14. MySQL's fulltext search has a minimum word length, which is 4 by default. Shorter words are not included in the index (and neither are stopwords, i.e. common words like 'the', 'have' or 'some'). You can read a bit about it in PW's selector documentation, where you'll also find a link to MySQL's docs on changing minimum word length. Fulltext search is always a bit of double-edged sword, as the price for fast search for natural language is payed with omission of short and very common words (words present in more than 50% of the examined rows aren't taken into consideration), no matter if you use MySQL, Lucene or any other fulltext engine. Splitting search terms on whitespace and adding a % selector expression for each of them may be an option, though that puts more load on the server.
  15. I installed 3.0.11 and tested it, and here it worked, but there are so many different parameters that might interfere. So, just to be sure: You edit a page in CKEditor and select a media library from there, then upload an image (let's call it 'test.png') After that, PW should place the image and thumbnails in "site/assets/files/[iD of media library page]/". Can you confirm that the id CKEditor puts into the image tag is the id of the media library page you selected? Is the image there on the file system immediately after you upload it? If I recall it right, there were some issues with image uploading in certain settings when always_populate_raw_post_data was enabled, but I'm not sure if that still applies. Also, memory limits in php.ini might be worth a look. Generally, though, if you can upload images and get a preview, everything should be running fine. Do you have any other site modules installed?
  16. Don't need to copy anything manually (like site-default to site), the installer will do this for you. All you have to do is check out your desired branch and access the installer through http. It will take care of creating the neccessary file system structure.
  17. Thanks, @LostKobrakai, that's a good suggestion that adds a lot of readablity. I've amended the script.
  18. You can alter an existing table simply by issuing ALTER TABLE your-table-name ENGINE=InnoDB; Though you may want to keep the original MyISAM table around. Here's a small bootstrap script to drop into the templates folder that converts all tables, either inplace (if $keepOld near the top is set to false) or creating a copy and keeping the MyISAM tables around postfixed with "_orig". It also writes a timestamped SQL file into the templates folder that allows you to switch back to MyISAM. Small caveat: if you select to keep your old tables, those will replace the generated InnoDB tables on restore, which means that all PW changes in between are lost - this may or may not be desired. So to use it, simply drop it in the templates folder of the PW installation in question and run it from the command line. It will check if you MySQL version is recent enough. <?php /** * Convert all tables in PW's database from MyISAM to InnoDB */ include('../../index.php'); // Set this to false if you do not want to keep your MyISAM tables around // with an _orig postfix $keepOld = true; // ***************************************************************************** $sql = "select substring(version(), 1, 1) as vmajor, substring(version(), 3, 1) as vminor "; $stmt = $database->query($sql); if($stmt === false) die("Something went wrong determining the version number!"); $row = $stmt->fetch(PDO::FETCH_ASSOC); $versionOK = false; if($row['vmajor'] > 5 || ($row['vmajor'] == 5 && $row['vminor'] >= 6)) $versionOK = true; if(!$versionOK) { die("You need MySQL 5.6 or later for InnoDB fulltext support!"); } // Version check finished, get list of tables $stmt = $database->prepare( "SELECT table_name" . " FROM information_schema.tables" . " WHERE table_schema = '" . $config->dbName . "'" . " AND lower(engine) != 'innodb'" ); $count = 0; if($stmt->execute()) { $tbls = $stmt->fetchAll(PDO::FETCH_ASSOC); echo "Found " . count($tbls) . " tables not running on InnoDB" . PHP_EOL; if(count($tbls) == 0) { echo "Nothing to do!" . PHP_EOL; exit; } $ts = strftime("%Y%m%d_%H%M%S"); $restore = fopen("restore_to_myisam_{$ts}.sql", "w+"); echo "- writing restore commands to file restore_to_myisam_{$ts}.sql" . PHP_EOL; // Convert each table foreach($tbls as $tbl) { $tabname = $tbl['table_name']; echo $tabname . PHP_EOL; if($keepOld) { // Create a copy of each table, convert the new table, // copy the content and switch table names $sql = "CREATE TABLE {$tabname}_convert LIKE $tabname"; if($database->exec($sql) === false) continue; echo "... Created copy of " . $tabname . PHP_EOL; $sql = "ALTER TABLE {$tabname}_convert ENGINE=InnoDB"; if($database->exec($sql) === false) continue; echo "... Changed engine to InnoDB" . PHP_EOL; $sql = "INSERT INTO {$tabname}_convert SELECT * FROM $tabname"; if($database->exec($sql) === false) continue; echo "... Copied content to InnoDB table" . PHP_EOL; $sql = "RENAME TABLE $tabname TO {$tabname}_orig," . " {$tabname}_convert TO $tabname"; if($database->exec($sql) === false) continue; echo "... Switched tables" . PHP_EOL; fputs($restore, "RENAME TABLE $tabname TO {$tabname}_innodb," . " {$tabname}_orig TO $tabname;" . PHP_EOL); fputs($restore, "DROP TABLE {$tabname}_innodb;" . PHP_EOL); $count++; } else { // Convert tables in place $sql = "ALTER TABLE $tabname ENGINE=InnoDB"; if($database->exec($sql) === false) continue; echo "... " . $tabname . " converted" . PHP_EOL; fputs($restore, "ALTER TABLE $tabname ENGINE=MyISAM;" . PHP_EOL); $count++; } } fclose($restore); } echo "Converted $count tables from MyISAM to InnoDB" . PHP_EOL; Edit: incorporated @LostKobrakai's suggestion to avoid nesting if statements.
  19. Yes, arrays as class constants are only possible from PHP 5.6.0 onwards.
  20. That's strange. Could you do a few checks to narrow it down? Is the uploaded image present in the file system under site/assets/id of the media library page? Is the image tag in the output still present and if yes, what does it look like? Also, which PW version are you using?
  21. The mix of preg_replace_callback and str_replace here doesn't work (throws an "Array to string conversion" error), as the $match passed to the callable is an array of matches (with $match[0] being the entire matched string and $match[1..n] the first to nth capturing group). It would need to either be written as function replace($match){ return 'P. Jentschura'; } or, as the others wrote, simply get rid of preg_replace_callback completely and directly perform a str_replace. public function formatValue(Page $page, Field $field, &$value) { $value = str_replace('P. Jentschura', 'P. Jentschura', $value); }
  22. You need to save your change. For PW < 2.7: $of = $page->of(); $page->of(false); $page->set('text_1', 'test'); $page->save('text_1'); $page->of($of); Or for PW >= 2.7: $page->setAndSave("text_1", "test");
  23. Try it like this (notice the curly braces where the url of the first image is retrieved): echo "<a class='gallery' title='$article->title' href='$article->url'> <img src='{$article->product_image->first()->url}'> </a>\n"; Of course, you could simply move the PHP code outside of the string: <img src= '" . $article->product_image->first()->url . "'> If you want to retrieve the url of the second image, you can use $article->product_image->eq(1)->url.
  24. It's easy to overcomplicate things when reading through all the threads, so I'll try to draw up a simple example. In your Shop template's PHP code, you'll only need to iterate over your children (optionally filtered by template to only get your clothing categories) for the sub headline, then iterate over the clothing category's children to get all the articles for the gallery. <?php foreach($page->children as $category) { // optionally $page->children("template=your_category_template") echo "<p class='category'><a href='$category->url'>$category->title</a></p>\n"; echo "<div class='article_gallery'>\n"; foreach($category->children as $article) { echo "<a class='gallery' title='$article->title' href='$article->url'><img src='$article->imagefield->url'></a>\n"; } echo "</div>\n"; } I've used an assumed name for your pageimages field of "imagefield", this needs to be adapted to match your setup of course. Also, if the image field is set to return multiple images, you need to cater to that too using $article->imagefield->first->url. In your template for the category (shoes, socks etc.) you just need the inner loop. It may be tempting to use the same template for Shop and categories, but in the long run, it'll be easier to keep things concise with individual templates.
  25. Make sure you have dbHost configured as 127.0.0.1, not as localhost.
×
×
  • Create New...