Jump to content

sforsman

Members
  • Posts

    131
  • Joined

  • Last visited

  • Days Won

    5

Everything posted by sforsman

  1. I take it 'clndr' is the repeater-field? Your code is slow because you are executing a find on each chalet. You should be able to do the whole thing with a single selector (that uses sub-field selectors), e.g. $selector = "template=chalet, clndr.arrival={$dates}|{$todate}, clndr.book=0"; This should be very fast. If this doesn't solve your problem please elaborate on your design.
  2. I thought Joss said it was the resized image that was breaking the canvas. I doubt he is stretching the original image bigger?
  3. Well you could do that or you could just rename myimage.jpg => myimage.old.jpg and then rename myimage.400x0.jpg => myimage.jpg. I'm curious to see if it's the filename of the resized image that's causing the trouble. I would find it very odd if it did, but hey, your case seems weird to begin with and there's no harm ruling it out. Could you also paste the code/img-tag you have around <?php echo...->url ?>
  4. If you (temporarily) replace the orginal image with the resized version on your filesystem and revert to no resizing, does it still break? I'm just trying to pinpoint your problem for now.
  5. if ($input->get->sort) { // <-- Here you are reading sort from GET $sort = $sanitizer->pageName($input->post->sort) ; // <-- Here you are reading sort from POST. One is probably wrong. switch($sort) { case 'asc': $sort = "name"; break; case 'desc': $sort = "-name"; break; // we don't set a default here when we did not click link default: ; break; // <-- There's an extra semicolon and the break is pointless (they makes no difference though) } $input->whitelist('sort', $sort); $sorting = $sort; } else { // if not - then here we set a default sort } Check my comments on your latest code. PS. I'm pretty sure what you're trying to do could be achieved with a single selector.
  6. @netcarver Thank you for the comments! Exactly. You are correct. Actually I had this mentioned in an edit of mine, but I decided to remove it because generally I don't want to encourage using (VAR)CHAR, BLOB or TEXT (for storing decimals) - especially regarding ProcessWire-projects. The reason behind this is that you don't get the benefits of a real DECIMAL field while performing database-operations on the field - you could actually get very unexpected results. Consider things like indexes, ORDER BY clauses, querying based on a range (field BETWEEN a AND b), aggregates (AVG, SUM) or other arithmetic done on the field (price*quantity*discount). Of course if you are writing SQL queries, you could ask MySQL to CAST the field (and it will actually do this for you in some cases), but this would be a lot slower (not to mention ugly). Of course there are cases where you need none of this and then using a CHAR is perfectly fine! PHP is obiously a lot slower handling them, but if you're not processing large result sets then this doesn't matter either. However I had even more reason to edit it away due the ProcessWire context. I'll give you two simple examples just to demonstrate my point. Consider the following selector template=product, sort=-price, limit=5 If your price-field is a CHAR-field, your results would be all wrong. In your PageArray you'd have products with a price of $9 even if there was a product with $1000 price. MySQL sorts the text-based fields alphabetically, so anything that starts with the number 9 is bigger than something that starts with the number 1. Then consider template=product, price>=10, price<=20 PW would actually return products that have a price of $100, which we clearly didn't ask for. This is because PW sends the values quoted (i.e. '10' and '20') which causes MySQL to compare the values as strings (because the database-field is a TEXT-field). I don't really see a problem with altering the column - the module does it for you. PW requires ALTER permissions anyway. Besides, as I demonstrated, having a DECIMAL-field is the only proper way handling it in PW.
  7. I'm giving out an implementation which you can use while Ryan is considering this matter. It's based on Ryan's FieldtypeFloat and InputfieldFloat and it should cover all the basics. cd <pw_modules_directory> git clone https://github.com/sforsman/FieldtypeDecimal.git git clone https://github.com/sforsman/InputfieldDecimal.git To actually use them, you obviously need to tell PW to scan for new modules and then install them. Couple of notes Since the precision needs to be defined on the database-level, this module hooks ProcessField::fieldSaved and updates the database if you have changed the precision settings. You get a notification if it's been done. Be aware, if you decrease the precision you will obviously loose those decimals forever after the save - the database is immediteally and always modified. I don't consider this ugly because this is mandatory - one way or another. Due to the implementation of the DECIMAL type in MySQL, it's not possible to choose such default values that would be optimal for all of the different scenarios. Along with a dot, I prefer to accept decimals with a comma as well. This is because many humans separate them with a comma. As with InputfieldFloat, you can define the range of the values the InputfieldDecimal will accept. If you have a precision math library installed, the module will use it when doing the comparison. This will rarely make a difference but hey, what the heck. To be consistent as to how the DECIMAL type is created in MySQL, the digits-parameter refers to the the total number of digits - including the decimal parts (5.55 has three digits and two decimals). There's a few known "issues" (I prefer to call them "features", though)The min/max configuration Inputfields are still using InputfieldFloat. This means you need to separate decimals in your min/max range with a dot. The sanitizer currently uses is_numeric() to check the value, which means you can enter some weird stuff (like 0x539) and it's sent to the database. However MySQL obviously ignores such values and stores 0 for you. This should be improved later. The Fieldtype doesn't do much to the values and relies on MySQL to handle the necessary rounding etc. This is good in my opinion. However this also means that if you have set the precision to "2" and enter a value that doesn't have any decimals (e.g. "5"), MySQL will add the decimals (the DECIMAL type is afterall an exact fixed-point type) and that's what you will see after you have saved your value (e.g. "5.00") . Again, I consider this a good thing. Like InputfieldFloat, the InputfieldDecimal doesn't do any validation on the data - invalid values are just blanked. As I have intentionally hooked only ProcessField::fieldSaved, you need to manually either a) call $field->type->syncSchema() or b) hook Fields::save yourself if you are modifying the precision of a field through the API. Oh and I'm open to any ideas - at least regarding these modules.
  8. I am glad you started a thread on this topic. I agree it would be great to see a FieldtypeDecimal module shipping with the core. This is something that's actually on a TODO-list for a big project of ours. It should definitely be a separate module (in other words, leave FieldtypeFloat alone) because floats have a different purpose. The background of the problem is in how computers handle (or should you say, how they support handling) floating point values. It actually doesn't have anything to do with PHP or MySQL, even less with PW - although you can obviously feel the effect of it. Binary floating point values supported by the CPU/ALU/FPU, such as the commonly used IEEE 754 (C, Java, PHP and so on), are always approximations. They are used where speed matters the most and the tiny loss of precision is acceptable. When precision is needed, you actually need something that implements arbitrary-precision arithmetic (bignum). The resulting loss of speed is irrelevant in many cases, such as handling currency. The reason why I'm bringing this up is that even with a FieldtypeDecimal implementation, you would still need to make sure you are handling the values correctly in PHP. If you perform any arithmetic on the value using PHP's arithmetic operators, you are actually causing PHP to cast the value to a floating point representation. That would defeat our purpose here (because you could loose precision). Thus if you need to perform arithmetic on the value, you must use an arbitrary-precision arithmetic library. For PHP you have at least two good options BCMath - http://php.net/manual/en/book.bc.php (simple set of functions, built-in) GMP - http://php.net/manual/en/book.gmp.php (a much larger set of functions, requires an external library) Of course none of this matters unless you can first store the original value in the database without precision loss. This requires a DECIMAL field in MySQL - which indeed was the original topic of the thread Here's a few links for general information. I recommend you to read at least the first one - it's a simple introduction. http://floating-point-gui.de/ http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic http://en.wikipedia.org/wiki/Double-precision_floating-point_format http://en.wikipedia.org/wiki/Fixed-point_arithmetic
×
×
  • Create New...