Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/28/2022 in all areas

  1. You must write: `catch(\Exception $e)` as the object must be an instance of the Exception class or of a subclass (see/mean inheritance here) of the Exception class. A must read is this following blog post on Microsoft and then come back with questions if still any ?? https://docs.microsoft.com/en-us/archive/blogs/kcwalina/how-to-design-exception-hierarchies Excerpt from Krzysztof Cwalina (software architect) :
    2 points
  2. This week we’ve got a new core version on the dev branch (v3.0.204) and a new version of FormBuilder (v53) posted in the FormBuilder board. Relative to ProcessWire 3.0.203 version 3.0.204 has 23 commits containing a mixture of feature improvements and issue resolutions. While there aren't major feature additions here there are a lot of worthwhile improvements and fixes, and I'd recommend the upgrade if using the dev branch. See the dev branch commit log for more details. The new FormBuilder version includes various improvements but the biggest is a new version of the included InputfieldFormBuilderFile module that supports file/image uploads in forms. It has been improved with a preview option (for images), the ability to collect a description for each file, improved multi-file inputs, and more. The new options appear on the “Details” tab when editing a file field in FormBuilder. This new version (v53) is available for download now in the FormBuilder board. If you upgrade an existing installation with file fields, I’d suggest testing out those forms after upgrade, and also review the new options to see if they make sense for your form. Thanks for reading and have a great weekend!
    2 points
  3. A dumb question, disk or partition full ? You could also look at this answer on dba.stackexchange for identifying the issue: https://dba.stackexchange.com/a/48897/170766
    1 point
  4. Thanks @flydev ?? for identifying the error, and sorry @Roych for the inconvenience. This is now fixed in version 1.7.2 of Login History, display date format should no longer intervene with date difference calculations ?
    1 point
  5. @BrendonKozThanks for the interesting write-up. Generally speaking, with maps or chart graphics, there are two main ways to ensure accessibility: One is described neatly in this article: https://css-tricks.com/accessible-svgs/#aa-interactive-images e.g. the use of role=group vs. role=img, using role=list role=listitem, tabindex etc. In your map, you could turn your three floor groups into three lists. The other strategy is to output an unstyled + visually hidden table or ul/ol somewhere that represents the floors and rooms/areas. You would then simply put aria-hidden=true on the entire SVG. This strategy is certainly the most efficient. However, if you want to enable focusing areas with the keyboard (for people who can't use the mouse), you'd have to alter your SVG further, like the above example.
    1 point
  6. A dream comes true !!! There's a german saying: "Was lange währt wird endlich gut." (What lasts long finally becomes good.) Actually, I wanted to get off work and start the weekend, so I guess it will be nothing for the time being ?
    1 point
  7. I should've put this topic into the Dev Talk forum section; my mistake! If a moderator wants to move it, by all means... ? I'm sure this isn't the most elegant way to do this, but it's what I came up with in the time I had. I ended up using a (ProField) Combo Field (see attached image for schema) to store each individual object's attributes that I wanted to have some level of editability within the CMS, and then stored those in a simple Repeater field as part of the "floorplan" template. I'll lock down the class_name, class_addition, and svg_path fields to administrator level accounts as they will be maintained in a much more fragile way. I used a Pages::saveReady hook in ready.php to detect changes on the repeater template (all repeaters have a hidden system template) in order to read in a version of the floor plan SVG that had valid, but easily identifiable XML strings to be used for (dynamic) replacement - and then write out a modified version using said replacement. An example of that string is below -- the floor number is the only thing that differs between each {placeholder}-esque string. <g id="floor0_fill"></g> The hook would then loop through all of the data provided in each combo field to generate the layers as needed, and then save the new version of the SVG file, completed as expected. I'll provide the code below, but it's only intended as an example for what I did. // Floor plan page - dynamically generate the static SVG from a template, and saved page fields' data $wire->addHookBefore('Pages::saveReady', function(HookEvent $event) { // Get values of arguments sent to hook (and optionally modify them) $page = $event->arguments(0); if ($page->template != 'floorplan') return; // Only process if the content of the floorplan items has changed $changes = $page->getChanges(true); if (!isset($changes['floorplan_repeater'])) return; // Generate the individual item SVG element entries $repeater = $page->floorplan_repeater; $svg = []; foreach ($repeater as $item) { $name = $item->floorplan_item->name; $type = implode(' ', $item->floorplan_item->type); $path = str_replace("\n", "\n\t\t\t\t", $item->floorplan_item->svg_path); $level = $item->floorplan_item->level - 1; // fix offset as set from PW ComboField's Select type $class = $item->floorplan_item->class_name; $full_class = $item->floorplan_item->class_addition ? "{$class} {$item->floorplan_item->class_addition}" : $class; $svg[$level][] = " <g id='floor{$level}_{$class}' class='{$type} {$full_class}'> <a class='item' xlink:href='#content-skip'> {$path} <desc>{$name}</desc> <text class='label' x='40' y='70'>{$name}</text> </a> </g>"; } // Open the SVG template (floorplan-template.svg), replace the content where needed, and save to the final SVG file (floorplan.svg) $path = $this->wire()->config->path('templates') . 'svgs/'; $svg_template = $this->wire('files')->fileGetContents("{$path}floorplan-template.svg"); if ($svg_template === false) { $this->error("The SVG template file could not be found: \"{$path}floorplan-template.svg\"", Notice::log); return; } foreach ($svg as $index => $floor) { $svg_template = str_replace('<g id="floor'.$index.'_fill"></g>', implode("\n", $floor), $svg_template); } $this->wire('files')->filePutContents($path.'floorplan.svg', $svg_template); }); It took me quite some time to find the proper way to identify a file path in ready.php!! That alone might be useful to someone. PW's filePutContents method (which also sets chmod) needed a path formatted in a specific way before it would work, and I wanted to do it the PW way, rather than the standard PHP way. Anyway, moving on... At this point all of the data was in the database, the SVG was generated dynamically from a template, and I moved on to dynamically generating the hidden definition list elements (that provide directions to each selectable object on the map, per floor), and the form elements that filter which map object is being highlighted on the map (with directions) at any given time. Lots of class/id/data massaging trickery, for sure! ...like the one below which was especially fun (and extremely ugly code). // Example Output: <span class="badge">G</span> <span class="badge">2</span> // Example Input: [0 => 'ground', 2 => 'two'] $badges = '<span class="badge">' . implode('</span> <span class="badge">', explode(',', str_replace('0', 'G', implode(',',array_keys($properties['floors']))))) . '</span> '; ? It's all working as of today, I only have some cleanup and optimizations to do - and the staff have just decided to do major furniture changes. ?‍♂️ At least the coding part is done! Back to the drawing board on the Illustrator file though!
    1 point
  8. Maybe this can be helpful ========================================================================================= $page->images->first(); // first image $page->images->last(); // last image $page->images->eq(0); // first image $page->images->eq(1); // second image ========================================================================================= Find the total number of pictures // Get the page that holds the the pictures $p = $pages->get('/path_to_page/'); $numberofimages = $p->images->count(); echo $numberofimages; ========================================================================================= images is an array ... see all the array elements inside the array images 1) Get a Page who has images $p = $pages->get('/path_to_page/'); 2) this gets all the elements $array = $p->images->getKeys(); 3) and this outputs to see them echo implode($array); ========================================================================================= Because an array starts with item number 0 and not 1 ... the last item number in the array is one less than total counted // echo $n; show the total counted number // echo $n--; show the total counted number minus 1 ... this is the last item in the array Note that when you upload an image in the backend by default it will be the LAST one added If you want to output the images in a gallery on the front and want the latest uploaded image to be the first in the gallery, you have to reverse the backend image order: Example: $var_page = $pages->get('/path_to_your_page/'); foreach($var_page->images->reverse() as $image) { echo "<a href='$image->link'><img src='$image->url' alt='description' width='' height=''></a>"; } ========================================================================================= F.
    1 point
  9. Check also if mod_rewrite is enabled in your XAMPP settings (and if all other requirement are given). To proof you can create a simple info.php file in your root folder containing <?php phpinfo();?> Greets!
    1 point
×
×
  • Create New...