Jump to content

nik

PW-Moderators
  • Posts

    294
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by nik

  1. I'm sure there's a better way - if only I knew what you're trying to achieve exactly ;).

    Here's an example of a page structure to demonstrate what's happening:

    post-481-0-96494100-1384969656_thumb.png

    With "limit=2" your code prints out:

    cat1
    cat2
      child2.1.1
      child2.1.2
      child2.2.1
      child2.2.2
    cat3
    

    And with "limit=3":

    cat1
    cat2
      child2.1.1
      child2.1.2
      child2.1.3
      child2.2.1
      child2.2.2
    cat3
    
    

    Reading the code, it's pretty much expected output to me, but obviously not the one you're after :). You're printing first two (or three) "child" pages under each "subchild" page found under children of "/mypage/" ("cat" pages). (Edit: and leaving all divs open.)

    So, what is the output you'd like to see with the page structure outlined above?

    (Edit 2: Fixed my examples...)

    (Edit 3: Really fixed my examples... It's not my day.)

    • Like 2
  2. Those empty items you're seeing are indeed the repeater's "ready items" like Mats pointed out. But while that filter works for you now, I wouldn't rely on the date being empty: when building a test case I changed some formatting options for the date field after already having created some events and ended up in a situation where the dates weren't empty for the pre-existing events. So I'd recommend filtering by the status to exclude unpublished items (filter("status=1")).

    But this is only a work-around as we're dealing with a bug here. A bug that raises its head only when certain conditions are met. Like you're saying, the extra items appear only after sorting by "eventdetails.date". To be more specific, the items appear whenever the PageArray is being filtered or sorted with a selector using a field inside the repeater. What's even more interesting is that this only happens for "untouched" repeaters. If the repeater contents is referenced in any way before filtering this actually works!

    OK, this is getting weird enough. I'm filing a bug with some instructions for Ryan to reproduce this odd behavior. I'll edit this post and add a link to the issue a bit later.

    Edit:

    See the issue here for some more details: https://github.com/ryancramerdesign/ProcessWire/issues/275

    • Like 4
  3. Sure it makes sense, especially the redirect part. And there's nothing wrong with saving something to the session either. This is pretty simple stuff and I'm not sure there are too many ways to do it - so no ProcessWire tricks to share.

    Looks like you've nailed it already, nice and simple. Only thing I haven't tried is saving the whole post data at once into session. And if that didn't work, you could always save individual values instead of the whole structure.

    So nothing much to say, but didn't want to leave your question unanswered either :).

    • Like 1
  4. $allresults is a PageArray having Pages where "template=chalet" and "fireplace=1". There's no way a search with "template=repeater_calendar" could match that set, as the template is different.

    I'm not sure I understand what you're trying to achieve exactly, but it looks like there's a little confusion between regular pages and repeater items (which are stored as pages as well). You could try and find the matching repeater items first (replace $allresults with wire('pages')) and then use only those matches that have the right properties for the page itself. If repeater "calendar" exists only in template "chalet" you'd only need to filter out those results where property "fireplace" does not match 1. And of course skip unpublished repeater items at once (see the code example in my previous post in this thread).

    Hope this helps (if I even understood you right). :)

    • Like 2
  5. Fieldtype Float lacks the possibility to specify output format at the moment (see https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeFloat.module#L56).

    But of course you can use number_format() yourself wherever you're outputting prices:

    echo number_format($page->price, 2, ',', ' '); 

    This gives "12 345,67" for the value 12345.67.

    If you've got several places where this field is being used (and/or several price fields), another option would be yet another hidden text field for storing the formatted value when the page is being saved.

    I have set the "Number of decimal digits to round to" to 7 - this should be correct to make prices possible up to 99999.99, right?

    Nope :). That option is to specify how many digits are being saved after the decimal separator, not before it. See http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html for the limits of float in the database - I don't think they will be an issue here.

    • Like 1
  6. Now you've got me confused. I think there's an error in your logic that can't be solved - not with a generic solution anyway. At first you said:

    Thanks! This helps me avoid empty results but doesn't seem to help specifying the search further. Eg. "rowling potter" now returns both the right post and other books made by rowling. The ideal result would be to only match the harry potter book by rowling. 

    Does that make sense?

    And then later on:

    Thanks! That almost does it, I think. Seems like it requires a match in both author and title, though. It would be fine for searches like "harry rowling", but wouldn't work for just "harry".

    So, you'd like "harry" to return all pages with "harry" in any of your search fields. This could be interpreted as one of the following:

    1. give pages with all words in any of the search fields
      • ​$ret = find("title|author*=$q") // exact phrase actually, but #1 isn't the right one anyway  
    2. OR give pages with any of the words in any of the search fields
      • $ret = find("title|author*=" . str_replace(" ", "|", $q)); // first solution by diogo 
    3. OR give pages with at least one of the words in all of the search fields (not necessarily the same word matching all the fields)
      1. $q = str_replace(" ", "|", $q);
        $ret = $pages->find("author*=$q, title*=$q"); // what I proposed earlier 

    Now, if I've understood you right, making a search "rowling potter":

    • should not give all pages with "rowling potter" in any of the search fields (#1)
    • should not give all pages with either "rowling" or "potter" in any of the search fields (#2)
    • should not require "rowling" or "potter" in all of the search fields (#3).

    Instead, you'd want it to give, hmm, all pages with one of the words matching the title and another one matching the author, unless there aren't any when it should give all pages matching any of the words in any field - or something like that. And we're talking about two words and two fields in this example, while your code example mentions actually four fields already. Looks like an impossible job for a generic selector/code solution.

    Now looking again what Wanze said I feel like he's been right all along: if you need anything more than a trivial match (one of #1..#3 given above), your only option may well be multiple search fields. One for each search field you need to handle in a special way that is. Then the search would be for example author:"rowling", title:"potter" and you could even give an option to choose whether AND or OR should be used (author: "rowling" AND title:"potter" <--> author:"rowling" OR title:"potter"). Now you actually could build a generic handler.

    Multiple fields lets the user define more precisely what they're after but then again they also require the user to understand which field to use for different searches. Maybe a generic search field + solution #2 for those who just want to find what they're looking for and an advanced search for those who need to refine their search to get only the results they're really after?

    If there's lots of data and giving some extra matches along with the exact ones (#2) really is a problem, then an advanced search could be the way to go. My personal preference is one single search field giving properly ranked results instead of a monstrous hard-to-fill form maybe giving me only the one match I'm after, but I see there's a place for the latter as well.

    Sorry for the (too) long post. I got a little carried away. :)

    • Like 6
  7. This should do it too (slightly modifying what diogo proposed at first and what I guess Wanze was saying as well):

    $q = str_replace(" ", "|", $q);
    // find pages having at least one of the words both in author field AND in title field
    $results = $pages->find("author*=$q, title*=$q");

    Plus some sanitation probably.

    • Like 1
  8. Hi Gespinha,

    ProcessWire is trying to tell you that "projects" is not a valid selector. See http://processwire.com/api/selectors/ on how to write selectors, this being the key here: "An individual selector consists of three parts: the field you are looking for, an operator (like an equals '=' sign), and the value you want to match. For example, a basic selector might be: title=products".

    So you could use for example "name=products". But just fixing the selector is not enough here; you're using find() which returns a PageArray (even if there's just one match), not a single Page. If you're trying to get a specific page, you could use get() instead. It works like find() but returns only the first match (a Page object). Or you could say find()->first()->url to access the first found Page inside the returned PageArray.

    • Like 4
  9. Hi muzzer!

    Did you already find out what was causing this odd behavior? I tried to reproduce what you're describing but I'm getting all those five pages returned with "title^=A".

    I guess you tried both selectors with the exact same setup? So no chance you've got a limit of some kind somewhere?

    You could also try those selectors with the SelectorTest module, just to eliminate other code lurking around. And with debug mode on try to find the actual database query for both (you can see all queries printed out at the bottom in the admin when debug is on). Maybe there's something there that helps finding the cause.

    • Like 1
  10. @Roope: Assigning an object does not copy the contents of the object, only its identifier. After the assignment to $slides, the variable holds the same object identifier as $page->advertize_homepage. So you're actually using the very same object there, which explains the behavior you're facing.

    Like Fokke said, you should use clone to make a copy of an object to keep the original object intact. See http://php.net/manual/en/language.oop5.references.php for more information on objects, object identifiers and references in PHP5.

    • Like 1
  11. What you did earlier for table "field_body" was correct - I was trying to say don't apply the same fix blindly to all keys named "data" as they're not all the same.

    So, for table "field_body" change "KEY `data` ( `data` )" to "FULLTEXT KEY `data` ( `data` )" (as column "data" is of type MEDIUMTEXT in that table). But for table "field_display_specialty_footer" leave the key to what it was ("KEY `data` ( `data` , `pages_id` , `sort` )") as column "data" is not of type TEXT/BLOB there.

    • Like 3
  12. Do the change only if the error is #1170 and the mentioned column is of type TEXT/BLOB (may be with a prefix TINY/MEDIUM/LONG too). In the table "field_display_specialty_footer" column "data" is of type INT(11) and should cause no trouble ("KEY `data` ( `data` , `pages_id` , `sort` )" is correct).

    So first see the error and only change what's actually needed.

  13. Looks like the key "description" wasn't exported quite right as the table structure isn't what it is when created by ProcessWire. Try changing "KEY `description` ( `description` )" to "FULLTEXT KEY `description` ( `description` )", that seems to fix the issue for me at least. And the same fix for other file/image field tables at least.

    I haven't got a clue why this has happened (SQL Buddy problem maybe?), but I hope changing the key definitions gets you around the problem!

  14. Yep, seems to work like you described Soma here as well.

    This is what I'm seeing: when a repeater field "xx" is added to a template "yy", no data is written into field_xx for pages with template "yy". And because selector "zz.count" relies on column "count" in field_xx, the selector doesn't work. But when such a page is saved the next time, a row with proper "count" value is written into field_xx and the selector works as expected.

    I guess those rows should be written for all pre-existing pages of the template when a repeater is added. Either that or some more SQL to cover the non-existing rows when <repeater>.count is used.

    • Like 1
  15. Thanks adrian!

    I actually thought I had fixed that months ago... And I had, but the changes unfortunately never made their way into GitHub until now.

    Anyways, multi-lingual titles are now fixed. Also, I pushed a little new feature as well: now you're able to choose a role and page permissions are shown for that role for each listed page. Hovering those yes/no texts gives a short explanation (as the titles are just single letters to keep it compact).

    • Like 3
  16. Yes, there is a hardcoded max of 999 for page numbering (defined here). Built-in pager does give you pagination links further than that, but they only work for numbers less than a thousand. You just have to take care of the rare occasions when for example a search would give more than (999 * pages_per_result_page) results. As the guys are saying in that other thread (I'm sloow today).

    But that's just how far the page numbering will go and has nothing to do with how many pages ProcessWire is capable of handling without any problem. We've got a site with 30000 pages and another one with 15000 pages. The bigger one is running nicely even without any kind of caching at the moment - and there is a bit more complex than just trivial search involved there. And no performance problems with the smaller one either, just to be clear =). There are even bigger PW sites around I'm sure. I think at least Antti has one in his hands and most probably others do as well.

    Sure one has to think a bit how to approach things to keep everything nice and fast. But it doesn't require any magic to stay on that road. Common sense and some testing along the way to see little things aren't piling up and you should be fine. In my opinion anyway. :)

    And I'm talking about the amount of pages here, not making any statement on whether to have several small sites in one install or not.

    • Like 3
  17. First of all, in my opinion you're giving a bit too much information about your live site here - domain and username, plus no proper sanitation apparently. Luckily the error is before actual login call and no password can be seen ;).

    So, as the error message says, your selector value wasn't properly escaped. Looks like you're running a find() with only the raw username given somewhere ("First Lastname" in this case, without the quotation marks). This could be something else, but do remember that all user input should be sanitized before using it in your code. At least run the input through $sanitizer->selectorValue() or do some more specific kind of sanitation depending on the situation. If all the usernames are formed like "first-lastname" then do check that's what you've got in before using the value and handle the error properly.

    • Like 2
  18. Regarding the function. I read it as:

    if $n is divisible by 2

            echo('odd');
        }else (if not){
            echo('even');
     
    But I expect if $n is indeed divisible by 2, then the first each should read even, not odd. Or am I reading it wrong?

    You are reading it wrong :).

    '%' is a modulus operator giving you the remainder of the division of its operands. For example 10 % 3 = 1 (10 = 3 * 3 + 1). So your first if actually means "if $n is NOT divisible by 2".

    • Like 1
  19. You can use a slightly different form of foreach to get also the index on each iteration, like this:

    foreach($children as $i => $child) {
        echo doAlt($i) . $i;
    }
    

    That should do the trick. Without the inner foreach of course.

    • Like 1
×
×
  • Create New...