Jump to content

Cybermano

Members
  • Posts

    70
  • Joined

  • Last visited

Posts posted by Cybermano

  1. Hi everybody. 
    I pull up this post for the same problem exporting/importing pages with Export/Import.

    I have the same template with same fields into two site ( let's call them "A" and "B") and same installation.

    Spoiler

    Fields:
    Title, as a PageTitleLanguage field
    headline, as a TextLanguage field
    embed_code, as a  Textarea field.

    Templates have same access, family policy etc. etc.


    Setup:
    ProcessWire  3.0.229
    Textarea (Multi-language)  1.0.0
    Text (Multi-language)  1.0.0
    Page Title (Multi-language)  1.0.0
    Languages Support  1.0.3
    Languages Support - Fields  1.0.1
    Languages Support - Tabs  1.1.7
    Languages Support - Page Names  0.1.3
    Pages Export/Import  0.0.1

    Same Languages setup on both sites: default as italian language, en as english and de for german (this is hidden, actually we're only using "it" and "en" into these sites).

    Well, from site A to site B I can correctly export and import the pages.

    But the odd behaviour is that from site B to site A, after the import test performed correctly, the  "Fatal Error: Uncaught Error: Call to a member function setLanguageValue() on null in wire/modules/LanguageSupport/FieldtypeTextLanguage.module:160 " occours on the import "commit".

    Spoiler

    Yow… Fatal Error: Uncaught Error: Call to a member function setLanguageValue() on null in wire/modules/LanguageSupport/FieldtypeTextLanguage.module:160

    #0 [internal function]: FieldtypeTextLanguage->___importValue()
    #1 wire/core/Wire.php (425): call_user_func_array()
    #2 wire/core/WireHooks.php (968): Wire->_callMethod()
    #3 wire/core/Wire.php (484): WireHooks->runHooks()
    #4 wire/core/PagesExportImport.php (957): Wire->__call()
    #5 wire/core/PagesExportImport.php (643): PagesExportImport->importFieldValue()
    #6 wire/modules/Process/ProcessPagesExportImport/ProcessPagesExportImport.module (639): PagesExportImport->arrayToPage()
    #7 wire/modules/Process/ProcessPagesExportImport/ProcessPagesExportImport.module (328): ProcessPagesExportImport->processImportItemToPage()
    #8 wire/modules/Process/ProcessPagesExportImport/ProcessPagesExportImport.module (251): ProcessPagesExportImport->processImportSubmit()
    #9 wire/modules/Process/ProcessPagesExportImport/ProcessPagesExportImport.module (76): ProcessPagesExportImport->processImport()
    #10 wire/core/Wire.php (413): ProcessPagesExportImport->___execute()
    #11 wire/core/WireHooks.php (968): Wire->_callMethod()
    #12 wire/core/Wire.php (484): WireHooks->runHooks()
    #13 wire/core/ProcessController.php (361): Wire->__call()
    #14 wire/core/Wire.php (413): ProcessController->___execute()
    #15 wire/core/WireHooks.php (968): Wire->_callMethod()
    #16 wire/core/Wire.php (484): WireHooks->runHooks()
    #17 wire/core/admin.php (160): Wire->__call()
    #18 wire/modules/AdminTheme/AdminThemeUikit/controller.php (15): require('...')
    #19 site/templates/admin.php (43): require('...')
    #20 wire/core/TemplateFile.php (328): require('...')
    #21 wire/core/Wire.php (413): TemplateFile->___render()
    #22 wire/core/WireHooks.php (968): Wire->_callMethod()
    #23 wire/core/Wire.php (484): WireHooks->runHooks()
    #24 wire/modules/PageRender.module (574): Wire->__call()
    #25 wire/core/Wire.php (416): PageRender->___renderPage()
    #26 wire/core/WireHooks.php (968): Wire->_callMethod()
    #27 wire/core/Wire.php (484): WireHooks->runHooks()
    #28 wire/core/WireHooks.php (1094): Wire->__call()
    #29 wire/core/Wire.php (484): WireHooks->runHooks()
    #30 wire/modules/Process/ProcessPageView.module (184): Wire->__call()
    #31 wire/modules/Process/ProcessPageView.module (114): ProcessPageView->renderPage()
    #32 wire/core/Wire.php (416): ProcessPageView->___execute()
    #33 wire/core/WireHooks.php (968): Wire->_callMethod()
    #34 wire/core/Wire.php (484): WireHooks->runHooks()
    #35 index.php (55): Wire->__call()
    #36 {main}
    thrown (line 160 of wire/modules/LanguageSupport/FieldtypeTextLanguage.module)

    It seems that the PageTitleLanguage can't save the value: I find the created pages only with the name (url), but not the title (mandatory field)...

    Anybody has an idea?

    Many thanks in advance.

     

    P.S.
    line 160 in FieldtypeTextLanguage.module is in a foreach into the public function ___importValue(...) :

    $importValue->setLanguageValue($language->id, $languageValue);

    If it's important, but I dont't belive, into both sites the languages id are exactly the same (default = 1010, en = 1021). Also the fields have the same name.
    I can't explain why is "null" the $importValue, that is derived from line 156: 

    $importValue = $page->get($field->name);
  2. I would advice all you that the geocoder API is no longer accessible in the format of the current module.

    I have an error geocoding address and the return message from nominatim.openstreetmap is: 
    Using the URL /search/ and /reverse/ (with slashes) is no longer supported.
    Change url from /search/?q=Berlin in /search?q=Berlin

    Also complete addresses are changed, see below:

    File not found: API no longer accessible via this URL
    
    Using the URL /search/ and /reverse/ (with slashes) is no longer supported. Please use URLs as given in the documentation.
    
    Examples how to change the URL:
    
    You use: https://nominatim.openstreetmap.org/search/?q=Berlin
    Change to: https://nominatim.openstreetmap.org/search?q=Berlin
    
    You use: https://nominatim.openstreetmap.org/search/US/Texas/Huston
    Change to: https://nominatim.openstreetmap.org/search?q=Huston, Texas, US
    
    See github issue #3134 for more details.

    See github issue #3134 for more details.

     

    Maybe editing ControlGeocoder.js fixes partially the problem?

    :343 L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', L.extend({
    change in
    L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search', L.extend({

    :370 L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', L.extend({
    change in
    L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse', L.extend({

     

    I have tested with simple addresses (italian street, number and city) ad it works fine again, both search and reverse.

    Posted a commit on Github:
    https://github.com/FriendsOfProcessWire/FieldtypeLeafletMapMarker/commit/63254dffea9bd504eb45b124d64fd5832e38f013

    • Like 4
    • Thanks 4
  3. Hi there,

    I'm testing a static call with JS to set a new view of the map (I need it on event change without refreshing the page), as found on Github and Stackoverflow:

    // frontend
    var mymap = L.map($('#mleafletmap1')).setView([45.53, 10.21], 2);
    
    // backend
    var mymap = L.map($('#_Inputfield_fm_mappa_map')).setView([45.53, 10.21], 2);

    This produces a TypeError: t.className is undefined.

    I looking for a solution, but didn't found it (...and I'm not a skilled js coder).

    Does anybody have an idea?

  4. Hi, is there anybody that knows how to easly disable "scrollWheelZoom" on admin page editing?

    Or is there a "module/field" settings development plan for map options in admin?
    (an overrideble setting in the field options could be great).


    I find a little annoying the zooming in/out of the map on page scroll.

    At the moment I put manually a js line of code in InputfieldLeafletMapMarker.js after line 24

    // line 24
    var map = L.map(mapElement).setView([lat, lng], options.zoom);
    
    // new line
    map.scrollWheelZoom.disable();

    But I'm not so happy to modify original modules... (on updates the modifications could be lose).

    The second approach that I have succesfully tested is to load a js file in admin, but it needs to completely initialize a new map, only with the add of an option in the declaration of the map init:

    var map = L.map('_Inputfield_fm_mappa_map', {center: [lat, lng], zoom: parseInt($('#_Inputfield_fm_mappa_zoom').val()), scrollWheelZoom: 0,} );
    Spoiler

    Complete code

    $(document).ready(function(){
    
        if ($('form#ProcessPageEdit').hasClass('YOUR_PW_TEMPLETE_NAME_TO_EDIT')) {
    
            var mapId = '_Inputfield_YOUR_FIELD_MAP_map';
    
            var lat = $('#_Inputfield_YOUR_FIELD_MAP_lat').val();
            var lng = $('#_Inputfield_YOUR_FIELD_MAP_lng').val();
            var zoom = parseInt($('#_Inputfield_YOUR_FIELD_MAP_zoom').val());
    
            var options = {
                zoom: 9,
                draggable: true,
                center: null,
                scrollWheelZoom: 0,
            }
            
            // var map = $('#_Inputfield_YOUR_FIELD_MAP_map');
            var map = L.map('_Inputfield_YOUR_FIELD_MAP_map', {center: [lat, lng], zoom: zoom, scrollWheelZoom: 0,} );
    
            var coder = L.Control.Geocoder.nominatim(),
            geocoder = L.Control.geocoder({
                geocoder: geocoder, placeholder: ''
            }).addTo(map);
    
            var marker = L.marker(
                [lat,lng],
                {draggable: options.draggable}
            ).addTo(map);
    
            // tiles provider according to module settings (not mandatory), like OpenStreetMap.Mapnik
            L.tileLayer.provider('YOUR_SELECTED_TILES_PROVIDER').addTo(map);
    
            var $map = $('#' + mapId);
            //var $latlng = $map.siblings(".InputfieldLeafletMapMarkerLatLng").find("input[type=text]");
            var $lat = $map.siblings(".InputfieldLeafletMapMarkerLat").find("input[type=text]");
            var $lng = $map.siblings(".InputfieldLeafletMapMarkerLng").find("input[type=text]");
            var $addr = $map.siblings(".InputfieldLeafletMapMarkerAddress").find("input[type=text]");
            var $raw = $map.siblings(".InputfieldLeafletMapMarkerAddress").find("input[name$=_raw]");
            var $zoom = $map.siblings(".InputfieldLeafletMapMarkerZoom").find("input[type=number]");
       
    
            $( ".InputfieldLeafletMapMarkerAddress" ).on( "click", function() {
                $(".leaflet-control-geocoder.leaflet-control").toggleClass("leaflet-control-geocoder-expanded");
                setTimeout(function() { $('input.undefined').focus() }, 300);
            });
    
            $lat.val(marker.getLatLng().lat);
            $lng.val(marker.getLatLng().lng);
            $zoom.val(map.getZoom());
    
            $zoom.change(function(event) {
                map.setZoom($zoom.val());
                map.setView(marker.getLatLng());
            });
    
            $lat.change(function(event) {
                marker.setLatLng([$lat.val(),$lng.val()]);
                map.setView(marker.getLatLng(), 9);
    
                coder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
                    var r = results[0];
                    if (r) {
                        $addr.val(r.name);
                        $raw.val(JSON.stringify(r.properties));
                    }
                })
            });
    
            $lng.change(function(event) {
                marker.setLatLng([$lat.val(),$lng.val()]);
                map.setView(marker.getLatLng(), 9);
                coder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
                    var r = results[0];
                    if (r) {
                        $addr.val(r.name);
                        $raw.val(JSON.stringify(r.properties));
                    }
                })
            });
    
            geocoder.markGeocode = function(result) {
                marker.setLatLng(result.center);
                map.fitBounds(result.bbox);
                $lat.val(result.center.lat);
                $lng.val(result.center.lng);
                $addr.val(result.name);
                $raw.val(JSON.stringify(result.properties));
            };
    
            marker.on('dragend', function(event) {
                var result = marker.getLatLng();
                $lat.val(result.lat).trigger('change.custom');
                $lng.val(result.lng).trigger('change.custom');
    
                //reverse geocoding displays in the adress field
                coder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
                    var r = results[0];
                    if (r) {
                        $addr.val(r.name);
                        $raw.val(JSON.stringify(r.properties));
                    }
                })
            });
    
            map.on('zoomend', function(event){
                $zoom.val(map.getZoom());
            });        
    
            // get the tab element where this map is integrated
            var $map = $('#' + mapId); 
            
            // Get closed wrappers around the map.
            var $inputFields = $map.parents('.Inputfield.InputfieldStateCollapsed');
    
            // Refresh the map when any of the wrappers open.
            $inputFields.on('opened',function(){
                window.setTimeout(function(){
                    map.invalidateSize();
                }, 200);
            });
    
            function initializeLeafletMap() {
                $(".InputfieldLeafletMapMarkerMap").each(function(item) {
                    var $t = $(this);
                    if (!$t.children().length) {
                        InputfieldLeafletMapMarker.init($t.attr('id'), $t.attr('data-lat'), $t.attr('data-lng'), $t.attr('data-zoom'), $t.attr('data-type'), $t.attr('data-provider'));
                    }
                });
            }
            
            $(document).ready(function() {
                initializeLeafletMap();
                $(document).on('reloaded', '.InputfieldLeafletMapMarker', initializeLeafletMap);
            }); 
    
        }
    
    });

     

    Any suggestions?

     

     

  5. Hi to everybody and special thanks to @Mats for sharing this big porting, to @gebeer @netcarver @dab for the hard implementations and  to @Ivan Gretsky to keep it alive again, but also to all the contributors and maintainers of this awesome module. 

    I'm testing it and it works really fine and easy.

    I would try to add an extra class to the markers and I followed this linked tip to Leaflet.AwesomeMarker properties for the main page with all the markers:

       $options = array(
            'useMarkerSettings' => true,
            'markerFormatter' => function($page, $marker_options) {
                $marker_options['icon'] = $page->icon; // Override the default icon for this marker.
                $marker_options['markerColor'] = $page->color; // Override the default color for this marker.
    			// Adding extra classes to this marker ??
                $marker_options['extraClasses'] = 'music-stage'; // Or dynamically from an option field: $page->stage_kind->value
                return $marker_options;
            }, 
    ...
    );

    But as you can see from the screenshot below, no classes are added to the icon (there is a blank space instead between the classes into <i></i> tag; actually it's always present, with or without the 'extraClasses' index into $marker_options).

    150269848_Schermata2023-06-29alle07_09_13.thumb.jpg.51c63adf3cb80514fa345c485f911983.jpg

    Am I missing something?

    P.S. The JS correctly loads  the object properties:

    mleafletmap1.addMarkerIcon(L.AwesomeMarkers.icon({prefix: 'fa', icon: 'music', markerColor: 'red', iconColor: 'white', extraClasses: 'music-stage'})

    Basically it would be nice to add extra classes to the whole marker (not only to the icon) to manipulate it with js (eg. filtering by type/class on a triggered event such as a button click or select change, or hiding from page if an event date is passed, like for exibitions/music lives and so on).

    Does anybody have any suggestions to do this?

    Thanks in advance.

  6. On 6/19/2023 at 10:42 PM, JayGee said:

    Hey @Cybermano 👋 ... remember me! 🤣

    Sorry had a crazy few weeks at work and then a holiday, but finally got around to reviewing your great contributions on this module. I tested it and everything looks great. I merged your changes and also combined our readme files and added a thanks note/credit for you too 🙂

    Thanks again - you've taken this module way beyond where I originally planned.

    Only comment is I noticed when you first install it, the module will error on the front end because no languages are selected. I guess this is obvious when you think about it, but wonder if we should make that a compulsory field or pre-populate with at least one language?

    Thanks
    J

    (Finally changed my name on here too lol)

    Hello, I'm back ... I spent a week of full immersion at work.

    I fixed the installation error (and pulled a request on GitHub). It was a bad condition in a public function. Sorry, I had missed it.

    P.S.

    Please, check your part of read.me (more or less, at line 14)
     

     ```<?php echo buildGoogleTranslateUrl('es');?>```

    Do you mean calling the function from the module as:

     ```<?php echo $translate->buildGoogleTranslateUrl('es');?>```

     

    • Like 3
  7. Hi @JayGee, of course yes!

    Thanks for all and don't worry: you did well to take a break after a hard work.

    I am very happy to have been useful: as soon as I can I check the error in the front end, but as you said I think it is possible to avoid it by assigning default values during module init.

    I'll get back to you shortly!

    Bye!

    • Like 1
  8. 10 hours ago, bernhard said:

    @Cybermano It should be quite easy to ignore cloned pages in your hook:

    $wire->addHookAfter('Pages::saved', function ($event) {
        $page = $event->arguments(0);
        if ($page->_cloning) return;
        bd($page);
    });

    Use tracy debugger to inspect the saved page objects and you can see if there are any helpful properties (like _added for example).

    I will surely do. Many thanks.

     

    Thanks again @bernhardperfect as always, of course.

    I will indagate the _added prop as suggested (maybe there is the reason that fires my hook without the _cloning return).

  9. Hi @bernhard, thank you for your suggestions and for your time too.

    You are right, there are unecessary $page->save(), but:

    let's say that I have a hook that check if there are pages with the same title (on page saved).

    Spoiler
    // CHECK TITLE DUPLICATES - ONLY FOR CURRENT YEAR
    if (wire('user')->isLoggedin()){
        $wire->addHookBefore('Pages::saved(template=foo)', function ($event){
        $page = $event->arguments[0];
        $alreadyPresent = [];
        $message = '';
    		// get items to check
            $items = wire('pages')->find('template=foo, parent.title='.date('Y'));
                foreach ($items as $item){
    				// store in array if not already present
                    if ( !array_key_exists(date('Y').'_'.$item->title, $alreadyPresent) ){
                        $alreadyPresent[date('Y').'_'.$item->title] = $item->title;
                    } else {
    					// for SuperUsers create links for id (to open page for editing)
                        if($item->editable()) {
                            $message .= '<b>'.$item->title.'</b> already exists for this year ('.date('Y').')';
                            $duplicates = wire('pages')->find('template=foo, title='.$item->title.', parent.title='.date('Y'));
                            $links = '';
                            $counter = 1;
                            foreach ($duplicates as $d){
                                if ($d->editable()){
                                    $links .= '<a href="'.$d->editUrl.'" target="_blank">'.$d->id.'</a>';
                                } 
                            if ($counter < count($duplicates)){
                                $links .= ' | ';
                            }                        
                            $counter++;    
                            }
                            $message .= ' [ page ids: '.$links.' ] ';
                        } else {
                            // for safe-editors (without editing permission)
                            $message .= '<b>'.$item->title.'</b> already exists for this year ('.date('Y').') [ page ids: '.wire('pages')->find('template=foo, title='.$item->title.', parent.title='.date('Y')).' ] ';
                        }
                    }
                }
            if ($message != '') {
                $page->warning($message, Notice::allowMarkup);
            }
        });
    }

    We have a site where guests can subscribe themselve on each year as art performers for yearly event, but only once.
    The subscription form is a FormBuilder form with manual send to page (to double check some contents filled in by guests, such as descriptions, social profile links or loaded images). 
    We have hundreds of requests every year, and we can't remember the name of all; so I made the previous hook that works fine.

    Well, this hook warns every time on cloning despite the title changing.

    The only way that I have found to not be warned is to set the original page as unpublished and, after cloning, to restore the original status.
    Otherwise with RobinS's hook, but activating "Make the new page unpublished" on cloning mask (but this is a one more passage respect your hook).

    Maybe I missing something or I making any mistake...

  10. Thanks a lot!

    Do you know if someone has ever thought about to insert those kind of features into the core?

    *edit*

    If sombody may need the same behaviour of Pagelist cloning (with unpublished status), I made a little hack to the @bernhard code:

    ...
    if($action === 'clone') {
    
        // get original page status
        $status = $page->status();
        // set unpublished
        $page->setStatus(2049);
        $page->save();
    
        // clone
        $copy = $this->wire->pages->clone($page);
    
        // get original name and store in an array
        $nameArr = explode('-',$page->name);
        // save cloned name (microtime style + 1)
        $copy->setAndSave('name', $nameArr[0] . '-' . ($nameArr[1] + 1));
        // add ' (copy ... + incremented timestamp)' to title
        $copy->setAndSave('title', $page->title . ' (copy ' . ($nameArr[1] + 1) . ')');
        // set unpublished status
        $copy->setStatus(2049);
        $copy->save();
    
        // restore original status to original page
        $page->setStatus($status);
        $page->save();
    
        $this->wire->session->redirect($copy->editUrl);
    
    }
    ...

    N.B.

    I used this trick (unpublishing the original page) due a personal hook that checks pages with same title (and warn if found one or more dupicates). Without the unpublished status for the original page, it seems that at first saving the title is the same also for cloned item... 

    The same results is obtained with the @Robin S hook, but flagging "Keep page unpublished" in the cloning mask.

  11. In the meantime, I have packed the backup site with its db, that looks correct.

    Looking into page differences, I've found that if I add a new item in the repeater field on the main page, this item uses a new template for the repeater:

    "repeater_vouchers1" instead of the original "repeater_vouchers". New template is created yesterday.

    image.thumb.png.d0da53c6aac02a065d46b51ee718d8f7.png

    Obviously the php code doesn't extract nothing, becuse all the selectors points to "template=repeater_vouchers, ... "

    But if I delete this item from the main page, it is deleted also from the admin for-page-XXXX container.

    This did not happen for the original articles... Very strange.

     

    For completeness, these updates were made yesterday:

    586315343_ModuleUpgrades.thumb.png.da5a1ce640fb7b9f280ee4379ef8d5ad.png
    The only one I think might have affected is core 3.0.210 (updated to migrate to TinyMCE): current repeater field is a FieldTypeRepeater, not the Matrix bundeled with pro ones.

     

    01/06 - 10:44
    Just finished to apply the same upgrades, step by step with double check on backup version of the site and all is fine: no repeater problems...

     

    • Like 1
  12. 6 minutes ago, Cybermano said:

    Thank for your patience, and sorry for my mistakes (I'm not skilled in dbs and I have the terror to destroy some/everything...).

    As far I know, we are using MySQL and newer had problems on our PW installations: I will check next days with coworkers of mine because I'm suerly closer to a code monkey than a webmaster.

    I already tried the way to export and import again all the tree structure from the parent, but with non luck. Both from the same server and from a weekly backup one where the repeaters are intact. No repeater items are imported in the public page.

    At this point I think the solution is to sync backwards the backup server to the developing one that we are using. But we will check tomorrow with clear minds.

    In the meanwhile I'll try to check with your latest hints and I will let you know.

    Thank you for your time: very very appreciated.
     

    Check on table is ok:

      $q = "check table field_vouchers";
        $statement = wire('database')->query($q);
        $results = $statement->fetchAll(PDO::FETCH_ASSOC); 
        echo '<pre>';
            var_dump($results);
        echo '</pre>';
    
    // dump result
    array(1) {
      [0]=>
      array(4) {
        ["Table"]=>
        string(29) "vouchers_newmc.field_vouchers"
        ["Op"]=>
        string(5) "check"
        ["Msg_type"]=>
        string(6) "status"
        ["Msg_text"]=>
        string(2) "OK"
      }
    }

     

  13. 3 hours ago, BitPoet said:

    $repeaterOwner should be the public page (i.e. 2905), so you now just created a superfluous entry in field_vouchers. You can delete that with 'delete from field_vouchers where pages_id=2906'. What stumps me is that a select on field_vouchers with pages_id 2905 returns an empty result, yet you still get the primary key error. Off the top of my head, I can only think of two scenarios where this could happen
    (a) your table's index got corrupted somehow, or
    (b) you're using InnoDB and there's an open transaction that should have inserted the row in question but hasn't sent a commit yet.

    To be on the safe side, you should probably export your repeater items and for-page-2905 using PagesExportImport and store that. This lets you recreate your repeater pages with identical ids even if PW decides to throw them away at some point.

    Afterwards, you can try running the SQL query 'check table field_vouchers' and see if the result shows any errors.

    Thank for your patience, and sorry for my mistakes (I'm not skilled in dbs and I have the terror to destroy some/everything...).

    As far I know, we are using MySQL and never had problems on our PW installations: I will check next days with coworkers of mine because I'm suerly closer to a code monkey than a webmaster.

    I already tried the way to export and import again all the tree structure from the parent, but with no luck. Both from the same server and from a weekly backup one where the repeaters are intact. No repeater items are imported in the public page.

    At this point I think the solution is to sync backwards the backup server to the developing one that we are using. But we will check tomorrow with clear minds.

    In the meanwhile I'll try to check with your latest hints and I will let you know.

    Thank you for your time: very very appreciated.
     

  14. 7 minutes ago, Cybermano said:

    Thanks: the query with 2095 it's also empty, but the second query to force inoculating the repeaters, performs again the same exception:

     Ouch… Error: Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2905' for key 'field_vouchers.PRIMARY' (in wire/core/WireDatabasePDOStatement.php line 168)

    Ok, maybe I didn't get it: I run the second query with $repeaterOwner = 2906;
    Your "<pre>" line appears with non other errors, but no repeater items are in page 2905.

     

    To be more clear:

    Public page with repeater field = id 2905

    Admin page (container of repeater) = id 2906

     

    Thanks for your time, and sorry because I'm not so keen on db queries... 🙂

    I beg your pardon, but I have to go out from office: I will follow from home.

     

  15. 5 minutes ago, BitPoet said:

    Oh, sorry. I've gotten turned around a bit here without noticing it. I must have looked too long at this line when I assembled the sql query:

        $vv = wire('pages')->find('parent=2906, template=230, sort=sort, include=all');

    The sql query with "2906" I had you do was wrong then and should have been 'select * from field_vouchers where pages_id=2905'. Can you run that again? Since there's still data there, let's take a look at what that is before I jump to conclusions (supposedly empty, but who knows, since it shouldn't have gotten into this state at all).

    Thanks: the query with 2095 it's also empty, but the second query to force inoculating the repeaters, performs again the same exception:

     Ouch… Error: Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2905' for key 'field_vouchers.PRIMARY' (in wire/core/WireDatabasePDOStatement.php line 168)

  16. 5 minutes ago, BitPoet said:

    That's okay. I just wanted to be sure that it's actually empty and not filled with incorrect data. Since the pages still exists, this little snipped should do the trick:

    if($user->isSuperuser()) {
    
    	$repeaterParent = $pages->get('/admin/repeaters/for-field-513/for-page-2905/');
    
    	$repeaterOwner = 2905;
    
    	$sth = $database->prepare(
    		'insert into field_voucher ' .
    		'(pages_id, data, count, parent_id) ' .
    		'values ' .
    		'(:page, :repeaters, :count, :repparent)'
    	);
    	
    	$params = [
    		':page'			=>	$repeaterOwner,
    		':repeaters'	=>	$repeaterParent->children()->implode(',', 'id'),
    		':count'		=>	$repeaterParent->children()->count(),
    		':repparent'	=>	$repeaterParent
    	];
    
    	$sth->execute($params);
    
    	echo "<pre>Inserted repeater</pre>";
    }

     

    Ok thanks, something it's moving... but:

    Yikes… Error: Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2905' for key 'field_vouchers.PRIMARY' (in wire/core/WireDatabasePDOStatement.php line 168)

    I've only changed field_voucher in field_vouchers (plural is the correct name)
     

  17. 11 minutes ago, BitPoet said:

    Can you take a look into the database and do a "select * from field_vouchers where pages_id=2906"?

       $q = "SELECT * from field_vouchers where pages_id=2906";
        $statement = wire('database')->query($q);
        $results = $statement->fetchAll(PDO::FETCH_ASSOC);
       
        echo '<pre>';
            var_dump($results);
        echo '</pre>';
    result:
    array(0) {
    }

    Is it possible?

     

    also this query has empty data:

        $field = $fields->get('vouchers');
        $table = $field->getTable();
        $q = "SELECT * from $table";
        $statement = wire('database')->query($q);
        $results = $statement->fetchAll(PDO::FETCH_ASSOC); 
        echo '<pre>';
            var_dump($results);
        echo '</pre>';
    
    // Output
    array(1) {
      [0]=>
      array(4) {
        ["pages_id"]=>
        string(4) "2905"
        ["data"]=>
        string(0) ""
        ["count"]=>
        string(1) "0"
        ["parent_id"]=>
        string(4) "2906"
      }
    }
    	

    P.S. Many thanks for your interest.

  18. 14 minutes ago, BitPoet said:

    Just to understand right, the repeater field is no longer on the template of your main page, right? (If it isn't, don't add it yet!)

    No, the repeater field is never gone away from the template.
    Only the repeater items are disappeared...

    P.S. Also tryed with this selector (ids are correct):

        $vv = wire('pages')->find('parent=2906, template=230, sort=sort, include=all');

    but the foreach doesn't save the items in the field...

     

  19. At the moment I have tried with:

    if($user->isSuperuser()){
        $page->of(false);
        echo $vp = wire('pages')->get('/admin/repeaters/for-field-513/for-page-2905/'); // the admin path where the repeaters are saved
        foreach($vp->children() as $v){
    		// Just for checking
            echo '<br/>';
            echo $v->id;
    
    		// add repeaer to the repeater field in the page
            $page->vouchers->add($v);
        }
        $page->save();
        $page->of(true);
    }

    The echo return the correct ids, but the whole code won't save in page the repeaters...

  20. Hi everyone.
    As per the title, this is the scenario:

    I have a main page with a FieldtypeRepeater with 4/5 elements added, where each repeater are called in other pages (linked to the respective repeater by the id: so the pages are url based with their repeater items).

    Accidentally, the repeater items were deleted from repeater field on the main page.

    (I know what you're thinking... "Accidentally? How is that possible?" 🤣- But please, trust me 😨: I don't know how they are literally "disappeared" from the page...).

     

    Actually only the main page has lost someting (a selection based on the deleted repeater ids), but not the other pages.

    I suppose if I rebuild the deleted items in the main page from scratch, I will create a big mess in the other pages with the old repeaters and the newer ones.

    And deleting all the other pages to rebuild them with the new repeaters is not an option.

     

    I already checked in the admin tree and the repeaters are still in /admin/page/repeaters/for-field-XXX/for-page-XXXX/

    Any ideas to "relink" those repeaters to the original main page (of course without losing original ids or recoding php templates and functions)?

    Is there any "magic" API?

    Many thanks in advance.🙏

  21. Spoiler

    Please, is there anybody here that know how to disable/remove inline styles?

    ...

    Found a way: declaring each tag style as invalid_styles at "field-level" (not in module settings), in Custom settings JSON text (surely also in file loading).

    {
    "invalid_styles":{
     "table":"width height",
     "th": "width height",
     "td": "width height",
     "tr": "width height"
    }
    "table_use_colgroups": false,
      "table_default_attributes": {
          "border": "0"
      }
    }

    A bit tedious, but it works.

    N.B. For us these settings are mandatory to use Bootstrap or our own classes for tables (and other elements).

    Thanks @WillyC: if you find a simplier solution it's welcomed. 

  22. Please, is there anybody here that know how to disable/remove inline styles?

    I tried using "invalid styles" like:

    table|th|tr|td=height|width

    or splitting in two separate rules 

    table|th|tr|td=heigh
    table|th|tr|td=width

    And I also tried JSON settings like:

    {
    "inline_styles": false,
    "table_use_colgroups": false,
      "table_default_attributes": {
          "border": "0"
      }
    }

    But no luck.

    In the JSON case the only override is the removal of colgroups and the assignment of border null, but inline style persists...

×
×
  • Create New...