Jump to content

BitPoet

Members
  • Posts

    1,279
  • Joined

  • Last visited

  • Days Won

    57

Everything posted by BitPoet

  1. Subfield addressing is implement by the Page class itself, so you're out of luck if you pass in anything else. If your properties are all tied to $page, it should work. Though, in any case, getting $page->body already calls wirePopulateStringTags implicitly when it encounters a replacement tag, so your tags will already have been replaced/emptied when you pass it to your own call to wirePopulateStringTags. I'm not sure what problem you're trying to solve, but if it's about giving editors an easy means to include loosely related information in the HTML they enter, without needing to code themselves, it may be worth looking at the Hanna Code Textformatter, which lets you define your own tags and assign the PHP code that generates the replacement value.
  2. It's probably just an oversight, so you should open an issue for it. In the meantime, you can fix it per hand by changing this line in FieldtypeComments.module's find method (around line 1000): if(in_array($f, array('id', 'status', 'created', 'pages_id', 'parent_id', 'created_users_id', 'upvotes', 'downvotes'))) { and add the stars field: if(in_array($f, array('id', 'status', 'created', 'pages_id', 'parent_id', 'created_users_id', 'upvotes', 'downvotes', 'stars'))) {
  3. BitPoet

    5 of a kind

    I guess that's one of the rules cut in stone, as it's been that way for a decade. Probably because not writing a blog entry is the way to avoid work load with the least palpable impact... Perhaps you could try selling blogging support as a coaching bundle. 2 hours consulting for topic selection, 2 hours for you creating a draft, a boss-approved deadline to get it edited for technical correctness by one of your client's specialists and two more hours for finalizing the wording and guiding them through the input. Three or four of these and the usual arguments/excuses (we don't have a fitting topic right now; our current topics are too technical; I've put it on the boss' stack but not heard back; we're waiting for [the release of product X|the traide fair|Christmas]) should be defeated. Some of the big misconceptions I've often found at clients are that writing a blog entry is easy and that obviously blog-worthy topics come up on a daily basis. It's always a steep learning curve for most to accept that you can't just quickly write a blog entry when you feel like it; you have to collect ideas and images beforehand and stick to a schedule blog entries are different from structured site content; writing them is a more creative process you often have to cut corners and sacrifice technical details to keep a blog entry interesting, so you often need two people to keep a balance there blogging takes time, too good blog content holds incentive value, be it because it's humorous or touching or because it has interesting information hard to find elsewhere a blog is not a company history; nobody wants to read plain facts there, so the writing needs to have a personal touch a good blog is a bit like an ongoing novel; it needs cliffhangers and suspense to keep readers' interest. Teasing them with upcoming products and events requires the client to have a reliable timeline for these though
  4. Just a few thoughts: I'd go with the legacy GeoIP databases and use geoip_country_code_by_addr (and optionally its IPv6 sibling). This should only be a few lines of code, plus, depending on the server you're running, perhaps a few more lines to download the current database every month (AFAIR, some Linux distributions even provide packages with cron jobs for that already included). Don't waste too much time trying to find the optimal solution by looking at browser headers etc. - those solutions don't exist. People surf through foreign proxies, use their en-gb browser on a trip to the U.S. or surf the U.S. page from an internet cafe in the UK. Make sure to avoid annoying the users. Embed the pointer to the native site in a prominent but pleasing way in the page, don't disturb them with javascript popups (modal or not). The first time, they'll click it away. The second time, they'll sigh and click it way. The third time... Whatever you do, never redirect a user automatically just because you think you know their origin or preferred language. They may well have a reason for wanting to access the URL they've entered or clicked. Instead, add a language switcher that lists all languagues/countries in their native language (the latter is not much of a point for U.S./UK/Ireland, but for the sake of completeness, I'll mention it here).
  5. That's interesting to read, because it's something I've been thinking quite a bit lately. As I'm working on complex ideas that need templates, fields and pages in their correct places, I'm more and more starting to use individual PW instances to keep things from getting cluttered up, but one day they'll need to be brought together on one system. I definitely won't want to recreate everything by hand, so some kind of export-import functionality will be essential. A lot of that can apparently be done with adrian's ProcessMigrator. I'll have to see how far this gets me, especially with multi-language installations and complex custom field types involved. I'd definitely prefer to build upon an existing module that re-invent the wheel from scratch. If I had to, though, I'd use PHP and PW bootstrapping. No sense introducing foreign tools or languages that may interpret data differently.
  6. It doesn't. Whether a template file matching the name of the template (or the alternative name in the template config) is in fact present in the file system isn't stored in the database. You could assemble a list of all templates without file and put that into a selector though: $missing = array(); foreach($templates->find("flags!={template::flagSystem}") as $tpl) { if(! $tpl->filenameExists()) $missing[] = $tpl->name; } // Now you can get all pages with missing template file: $pages->find("template=" . implode("|", $missing)); // Or just children $page->children("template=" . implode("|", $missing));
  7. $pages vs. $page?
  8. This is documented behavior. From PW's selector documentation:
  9. BitPoet

    Seperate Log ins

    Set a different session name for every PW instance. From config.php: /** * Session name * * Default session name as used in session cookie. You may wish to change this if running * multiple ProcessWire installations on the same server. By giving each installation a unique * session name, you can stay logged into multiple installations at once. * * #notes Note that changing this will automatically logout any current sessions. * @var string * */ $config->sessionName = 'wire';
  10. Edited away my reply since tpr said it all and better.
  11. Great to hear! I've created an issue and suggested the fix.
  12. Does it work if you change line 412 in core/WireFileTools.php from this: } else if($options['defaultPath'] && strpos($filename, '/') !== 0) { to this: } else if($options['defaultPath'] && strpos($filename, '/') !== 0 && strpos($filename, ':') !== 1) { ? /edit/ This is addressed at pwired.
  13. Definitely. On a load heavy site and when absolute exactness of the counts is important, there's no way around using the database directly (incrementing a page field simply isn't atomic).
  14. It shouldn't be hard to get the whole banner rotation thing up using PW's on-board functionalty. The only additional module necessary would be AdminCustomPages to view statistics. Here's how I'd do it: Create a bunch of templates for category and banner as well as categories and banners templates to group them together. The category template gets a view counter which we increment with every view of a banner through the category, and we'll use that counter to pick the next banner. The banner template gets a field for the category it belongs to, one for the URL to redirect to and, of course, the image field, optionally with size settings in the field configuration. Our "normal" templates get another page field in which we pick the banner category. We also add a "click" template to store each banner click with the remote IP. Thus we have the following templates with fields: banner_categories title field onlyWe create a banner categories page somewhere (it doesn't really matter where, can be under home). banner_category title (for the category selections) banner_cat_count (our counter) banners title field onlyLet's create one of these under home too. banner title (just for us) banner_image (image field, set to single image, size constraints in the field's config) banner_url (fieldtype URL, the address to redirect on click) banner_category (page field, single select, parent set to banner_categories page) click click_ip (text field)Our pages that should include banners get a new page field (single page, NullPage if empty) page_banner_category. Now we need two PHP templates: one to render the banner inside the page (let's name it "_banner_include.php") and one that does the counting and redirecting if a banner is clicked ("banner.php"). In banner.php, we simply add a click counter page under the banner page itself, then redirect to the configured URL: <?php $click = new Page(); $click->template = wire('templates')->get('click'); $click->name = 'click-' . time(); $click->parent = $page; $click->click_ip = $_SERVER["REMOTE_ADDR"]; $click->save(); $session->redirect($page->banner_url); In _banner_include.php, we increment the view counter for the category (we could also add a counter field to the banner template and increment it on the banner page), then use the counter value modulo the number of banners in the category to get the banner itself: <?php $banner = next_banner($page->page_banner_category); function next_banner($category) { global $pages; $banners = wire('pages')->find("template=banner, banner_category={$category}, include=hidden"); if( $banners->getTotal() == 0 ) return new NullPage(); $category->of(false); $category->banner_cat_count += 1; $category->save(); $category->of(true); return $banners->eq($category->banner_cat_count % $banners->getTotal()); } if( ! $banner instanceof NullPage ) { ?> <div class="banner"> <a href="<?= $banner->url ?>"><img src="<?= $banner->banner_image->url ?>"></a> </div> <?php } Now all we need in our regular pages' templates to render the banner: <?= $page->render("_banner_include.php"); ?> Getting an overview in the backend using AdminCustomPages should be quite easy too by just creating a custom page including a scipt that iterates over all the categories, reads the click counter, then iterates over each banner and counts the children (optionally limited by the timespan). A quick-and-dirty script (untested) to illustrate that: <?php foreach( wire('pages')->find("template=banner-category") as $cat ) { echo "<h1>{$cat->title}</h1>"; echo "<table><thead><tr><th>Banner</th><th>clicks</th></tr></thead>\n<tbody>\n"; foreach( wire('pages')->find("template=banner, banner_category={$cat}, sort=title") as $banner ) { $clicks = $banner->children->count(); echo "<tr><td>{$banner->title}</td><td>{$clicks}</td></tr>\n"; } echo "<tr><td colspan=2>{$cat->banner_cat_count} Views / {$clicks} clicks</td></tr>\n"; echo "</tbody>\n</table>\n"; } We could, of course, make things a little easier by grouping the banners under their category, and there's nothing major speaking against it. I used a different parent for the banners to have them all under the same URL, i.e. /banners/banner-name. All in all, it shouldn't take more than an hour to get things up and running this way.
  15. Aaron, a few questions to help us get a clearer picture: are you running your script from command line or in the webserver? if the latter, does php segfault or the webserver? if the former, which error code does the segfault message show? which versions of PHP, PW, MySQL (and, if involved, webserver) are you running?
  16. This line looks fishy, likely to create an infinite recursion (though assigning a page to its own page field shouldn't be possible normally): $pageModel->set("mapped_car", $pageModel); The second $pageModel in that line should probably be $pageCar.
  17. Does twiddling with the template's "Use compiled file" option help?
  18. @BFD, I've got a fork of ProcessWireUpgrade on github. Perhaps you could try if this fixes the issue without any config changes on your part (just make sure to download the dev-useragentfix branch to which the link points, not master).
  19. It's a php.ini directive and should be set there, if possible. If PHP runs as an apache module, you should be able to set php_value user_agent "PHP" there. Or you could set it in PW's init.php. ini_set("user_agent", "PHP " . PHP_VERSION);
  20. So now things are getting really wierd, as I'm sure when I tested it at work, I could reproduce the problem. Now at home and on a different server, I can't. The thumbnail comes out rotated correctly (without Exif information, of course).
  21. GD doesn't really deal with Exif (it can read the information, but that's it), so any image created through GD is going to end up without Exif information. From what I saw in the code of ImageResizer, IPTC (semantic information) is copied over to the new image but not Exif. All freeware PHP projects with Exif write support I know of are either dead or gone.
  22. In web development, never use PHP's sleep function (the few exceptions to this rule are not worth mentioning). $session->redirect sets a location header and according status code. By its nature, the header is processed by the user agent before any content is displayed to the user. So you either redirect with a header or present content to the user. You have two possibilities: 1. Do your form processing early in the page and either set a meta http-equiv="refresh" header with timeout and destination or let javascript redirect to the page like Fokke suggested 2. Use an intermediate confirmation page that uses a meta refresh header and to which you pass the success message and the final target (not much different from the first, but it's often easier to work around the problem of already included HTML headers this way)
  23. userAuthSalt is for PW's login system, but the error in the OP comes from MySQL. A few ideas to check: there might be another line further down in config.php where dbUser is set; something fishy may have gone on with the config file during the upload and it contains invalid characters; the entry for $dbUser in the mysql.user table may be limitied to 127.0.0.1 or % instead of localhost.
  24. Regarding (ii) and after a cursory glance at the JS: Store the page numbers in an attribute in the pager's spans in paginateTable In the marker's click event, calculate the row position through row.prevAll('tr').length Calculate the matching page number from the position and limit Find the matching pager item through the attribute in the first step and fire a click event on it
  25. This is MarkupAdminDataTable's expected behavior (wrapping the value in a link to the key) if you pass an associative entry to row(), so you'll have to build the complete HTML snippet for the column manually. Or, even better, make the checkbox and the link separate columns.
×
×
  • Create New...