Jump to content

Peter Falkenberg Brown

Members
  • Posts

    347
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by Peter Falkenberg Brown

  1. Hi @kongondo,

    This is so cool. Thank you VERY much. It works perfectly.

    I'm wondering what the best way to load it under certain conditions would be. Right now, it places the cursor in the field whenever I go into edit mode, not just on the initial edit that comes right after adding a record. In my ready.php file I have this:

    $this->addHookBefore('AdminTheme::getExtraMarkup', function (HookEvent $event) {
      $config = $this->wire->config;
      $url = $config->urls->templates;
      $config->scripts->add($url . "scripts/admin.js");
    });
    
    $pages->addHook('added', function(HookEvent $event) {
          $page = $event->arguments(0);
    
          if ( $page->template == 'book_sales' )
                {
    			.... etc....

    So, in the code that comes after the addHook('added') it only operates in the subsequent edit screen, but not when I go back to a record and click on edit.

    (At least I don't think so.)

    Is there a way to only initiate the cursor focus during that initial edit?

    Thank you again!

    Peter

     

    • Like 1
  2. Thanks, @kongondo...

    In the PW admin, when you click on "New" to add a record, the title field has focus, with the cursor in it.

    However, when you then hit save and get to the edit page, none of the fields have focus.

    These pages are part of the built in admin, so I'm wondering if they can be tweaked without editing the core files.

    Based on your description, it would seem that the New record page must have some type of focus mechanism, either with Javascript or HTML.

    What are your thoughts?

    Thanks!

    Peter

     

  3. Hi All,

    I'm using ready.php to add some values to new pages, so that after I type in the title of the page and hit save, when I get to the edit page of the full set of fields, certain fields have pre-filled values. The routine is working well, but I want to add one more item, to wit:

    - I want to set the field focus (i.e. the cursor is in that field) to a field called "list_price." Can that be done, in ready.php, and if so, what's the best method?

    Here's the code I have already:

    $pages->addHook('added', function(HookEvent $event) {
          $page = $event->arguments(0);
    
          if ( $page->template == 'book_sales' )
                {
                #.............................................
    
                $parent      = $page->parent();
                $parent_path = $parent->path();
                $last_item_number_selectors = "parent=$parent_path," .
                                              "sort=-item_number,"   .
                                              "$skiptrash,"          .
                                              "limit=1";
    
                $last_item_number = wire("pages")->get("$last_item_number_selectors")->item_number;
    
    			# the item_number has a 2 letter prefix, followed by 4 digits that have leading zeroes,
    			# and the number has to be incremented, while retaining the leading zeroes.
    
                $part1 = substr($last_item_number,0,2);
                $part2 = substr($last_item_number,2);
    
                $part2inc = intval($part2) + 1;
                $part2new = sprintf('%04d', $part2inc);
    
                $new_item_number   = $part1 . $part2new;
                $page->item_number = $new_item_number;
    
                #.............................................
    
                $admin_now = time();
    
                $page->list_date = wire(datetime)->date($format='Y-m-d', $admin_now);
    
                $page->list_year = wire(datetime)->date($format='Y', $admin_now);
    
                #.............................................
    
                $page->of(false);
                $page->save();
                $page->of(true);
                }
    });

    Thanks!

    Peter

     

  4. Thanks, @AndZyk,

    But adding the single quote marks didn't work. I still get this error message:

    Fatal Error: Uncaught Error: Call to a member function date() on null in site/ready.php:12
    
    #0 wire/core/WireHooks.php (1050): ProcessWire->{closure}(Object(HookEvent))
    #1 wire/core/Wire.php (485): WireHooks->runHooks(Object(Pages), 'saveReady', Array)
    #2 wire/core/PagesEditor.php (491): Wire->__call('saveReady', Array)
    #3 wire/core/PagesEditor.php (455): PagesEditor->savePageQuery(Object(Page), Array)
    #4 wire/core/Pages.php (799): PagesEditor->save(Object(Page), Array)
    #5 wire/core/Wire.php (420): Pages->___save(Object(Page), Array)
    #6 wire/core/WireHooks.php (951): Wire->_callMethod('___save', Array)
    #7 wire/core/Wire.php (485): WireHooks (line 12 of site/ready.php)

    Peter

  5. Hi All,

    Maybe because my brain is fried tonight, but I'm totally stuck on extracting the 4 digit year from a datetime field inside the ready.php file, on saving a page. Here's my code:

    $pages->addHook('saveReady', function(HookEvent $event) {
          $page = $event->arguments(0);
    
          if ( $page->template == 'book_sales' )
                {
                if ( $page->sold == 1 )
                      {
                      $page->profit = ($page->sale_price - $page->buy_cost) - $page->transaction_fee;
    
                      $page->sale_year = $datetime->date($format='Y', $page->getUnformatted(sale_date));
                      }
                }
    });

    The line that tries to get the sale_year, i.e.

    $page->sale_year = $datetime->date($format='Y', $page->getUnformatted(sale_date));

    breaks with a bunch of errors. Anyone have the right syntax?

    Thanks!

    Peter
     

  6. Hi @dotnetic,

     

    (An aside: I created a spreadsheet that does all of this very quickly. Easy as pie. However, in some cases, a PW database might be better, thus my questions. On the other hand, maybe trying to fit PW with the functionality of spreadsheets is a waste of time. You know... the right tool for the job.)

    Yes, the PagesSum module is exactly what I need. Thank you!

    But... in the Admin section, with the standard tree of page types (i.e. templates), assuming that I have a branch of pages called "sales," then where and how could I display the sum of those sales pages (from a field called "sale_price") on the admin page?

    I haven't adequately dug into the task of modifying the admin page. In a custom app, all based on php template docs, I would simply display that total on the apps version of the "home" page, i.e. like the Admin tree page. But in the PW Admin page, I haven't yet learned how to add a routine to display something like that on the top level admin page.

    Is there a document somewhere in the PW knowledge base on how to do that?

    I've already made one small modification to the admin's core files in the wire directory, in a file called "AdminTheme.php." In that file, in the routine

    public function ___getExtraMarkup()

    I change this code:

    if($isLoggedin && $this->wire('config')->advanced) {
    
    	# $parts['footer'] = "<p class='AdvancedMode'><i class='fa fa-flask'></i> " . $this->_('Advanced Mode') . "</p>";
    
    	$parts['footer'] = str_repeat('&nbsp;', 10) . "DB: " . wire('config')->dbName . "<br><br>";
    }

    ... so that the admin page would display the name of the database in use (to avoid a dev version using the live db by mistake).

    ( @ryan Ryan, I think this would be a good addition to the core.)

    I realize that it's a Bad Idea to modify core files, so in terms of modifications to the admin home/tree page, with the Sum function display, I'm hoping that there's a hook method, or some other way to get that data displayed on the page, without messing with the core files.

    Thanks!

    Peter

     

  7. Hi All,

    I haven't found this answer in the docs or forums. I know how to program a template that would display multi-page field calculations like a spreadsheet, e.g. with 100 pages, each with a dollar value in a field, display the total dollar value of a subset of the 100 pages based on a "sold" data field value.

    I know how to put that template / url / page behind a password.

    What I'm not clear about is whether or not PW has an easier method than that. For example, in the standard admin, create a page/template that has the summary fields in it and pull the calculations from the "item" pages whenever the summary page is accessed or a button is pressed. Or something like that. So that the calculations can be viewed in the admin without having to build a password protected, programmed front-end page.

    Of course, a spreadsheet can do all this easily, but after thousands of records, it becomes rather unwieldy, in my opinion.

    What do people recommend?

    Thanks,

    Peter

     

  8. Hi Ryan,

    When I read about the combo field, it almost seems like a jury-rigged version of a standard MySQL data table with column definitions.

    When I first came to ProcessWire, I had to get used to its splitting of the fields into separate tables.

    I'm not an expert DBA kind of person on advanced MySQL queries and indexing and things like complex join SQL statements, but how would you compare the traditional SQL approach of complex queries to both the standard ProcessWire method and the new Combo fields?

    My question might be too broad; not sure.

    Peter

     

    • Like 2
  9. Hi All,

    I thought I saw that a feature had been developed that allowed one to click "New" to add a new child page, and skip the name field page, and go directly to the edit page, with the name field already having the ID as the value.

    If that hasn't been developed, is there a way to do that?

    I've been scouring my posts and searching the forum because I know that I got advice from someone to set the name field to the ID using ready.php, using this code:

    $pages->addHookAfter('added', function(HookEvent $event) {
    	$page = $event->arguments(0);
    	if($page->template == 'item') {
    		$page->setAndSave([
    			'name' => $page->id,
    		]);
    	}
    });

    ... but I can't find the darn post in the forum. (I'm using the code above.)

    My client wants to skip the step where he has to add a fake name value (like 'n') which then gets overwritten by the ID, using the code above.

    Thanks!

    Peter

     

  10. Hi Folks,

    I am stuck, after scouring the API docs, module code, and forum questions.

    I'm trying to write code that upon the initial pressing of a search button will set the page number to something other than 1.

    For example, the query might return 50 pages, but I want to start by showing page 7, with the pagination boxes appearing on both sides of the highlighted box 7.

    Here's my code (setPageNum will only be used if it's an initial search button press (which I'll check with a hidden form field)).

          $results = $pages->find("$select_limit");
    
          $pager = $modules->get('MarkupPagerNav');
          $pager->setNumPageLinks($numPageLinks);
    
          $pager->setPageNum(7);
    
          $pagination = $pager->render($results);

    The returned pagination all looks good EXCEPT that it always starts at page 1 instead of page 7, like this:

    image.png.520d2b7c4e41082f3614870ebb5ecaf7.png

    Any help would be greatly appreciated.

    Peter

     

  11. Back in 2005/6, I built a SSG/CMS combination application, based on a Perl Framework that I had written.

    The magazines' editors input their stories via a CMS login, and then, when they were done, they clicked a button that sent a special secure command to the server to run a script that generated all of the pages as static HTML files. It generated thousands of pages blazingly quickly.

    Having done that, I think ProcessWire with ProCache accomplishes the same thing, since it also writes HTML files.

    But... ProcessWire is SO much better than my application ever was, for so many reasons.

    ProcessWire with ProCache gives us the best of both worlds.

    Peter

     

    • Like 5
  12. You're very welcome, @szabesz! (and thank you!)

    This thread started with my how-to questions about image migration. Besides the modules that @adrian and @kongondo mentioned, I didn't find any clear documentation about how to deal with image migration with comprehensive detail (I might have missed finding it). Of course, I read a number of pages about image scripting, but I didn't see info that covered all the bases.

    Adrian expressed skepticism about the stability of the module Kongondo mentioned, and Adrian's module didn't fit my specific needs, so I didn't use either of those modules, and decided to proceed with my own script.

    But my script didn't deal with cropped images (because I didn't have any), unless they're automatically brought over by the copy command I ran to bring in any image variations. Thus, my script might have missed some important things with images. I'm not sure.

    I'd love to see a how-to on this very topic, i.e. a comprehensive write-up of how to migrate images and catch every detail. My efforts were a "roll-your-own" attempt to do it, and it worked for me. But I have no confidence that I covered all the details of image migration.

    If I did, I'd love to hear about it. ?

    Peter

     

    • Like 1
  13. Hi All,

    I've added routines to the script to create a file of hrefs in the body field, and also a file of 301 redirects for an .htaccess file.

    There are so many edge cases with internal hrefs that I decided to edit them by hand, based on the list created. (For example, an href that links to a second internal PW page on the target domain that PW's url system on the source domain doesn't know about.)

    I also moved the chown command to include pages that didn't have images, because the file dir has to be owned by the domain and running the script as root ends up making the file dir owned by root.

    Again, I realize that this script may only serve a very small group of people who need to do exactly what I needed it for: to migrate many sections of pages from one PW domain to another PW domain that had a different section structure. I've successfully and quickly moved many sections and pages as of now, so I'm confident that the script is doing what I needed. If someone else finds it useful, that's grand. ?

    Here it is, below. Click the "reveal hidden contents" icon below to see it.

    Peter

    Spoiler
    
    #!/usr/bin/php -q
    <?php namespace ProcessWire;
    ###################################################################################################
    /*
    copy.section.php
    a script for ProcessWire installations, to migrate sections of pages.
    Version 1.1 - no license, no guarantees, use at own risk.
    
    I recommend running this script with the 'tee' command so that you can
    review any potential errors, i.e.:
    
    ./copy.section.php | tee output.txt
    
    peterbrown@worldcommunity.com - May 26, 2020
    https://datavarius.com
    #################################################################################################
    
    NOTE: @adrian has written a very nice module for migrating sections of sites, here:
          https://github.com/adrianbj/ProcessMigrator
    
    NOTE: I wrote this script to specifically copy a set of child pages under a section in
          one domain over to a new domain, for a narrow use-case that will not
          fit everyone's needs. It is undoubtedly missing complex solutions.
          It is not even close to the sophistication of Adrian's module.
          My second motivation to write it was that it was a learning exercise.
    
          => This is a "quick and dirty script," i.e. it's written with procedural code
             to simply get the job done quickly and correctly.
    
          => This script was written for sections of pages that share the same field template.
             Of course it could be modified for other scenarios.
    
          => This script also creates two files: one for hrefs in the body field
             and a file of 301 redirects for an .htaccess file.
    
          => This should be run as root, from the shell prompt.
    
          For multi-instance notes, see article at:
          https://processwire.com/blog/posts/multi-instance-pw3/
    */
    ###################################################################################################
    # SET UP
    
    # NOTE: please read through the script before using.
    # This was custom written for MY use, and you'll have to change some things, e.g.
    # you'll need to add your page fields below in the section "add fields here."
    
    use DomDocument;
    
    $now                   = time();
    $date_time             = date('Y-m-d-H-i-s');
    
    #.......................................................................
    # primary vars to change
    
    # primary site (site to import TO)
    
    $site1_root_index_file = '/home/USER/public_html/index.php';
    
    # secondary site (site to import FROM)
    
    $site2_web_doc_root    = '/home/USER/public_html/';
    $site2_full_domain     = 'http://DOMAIN.com/';
    
    # this is for chowning the new file dir with its files
    
    $site1_group_user      = 'USER.';
    
    # used for 301 directives
    
    $site1_domain          = 'https://DOMAIN.com';
    
    $site1_section_parent  = '/URL/URL/';
    $site2_section_parent  = '/URL/URL/';
    
    # set this to 'yes' to run through list and make href and redirects files and then stop
    # without making new pages
    
    $stop_after_rewrites_hrefs = 'yes';
    
    #.......................................................................
    # secondary vars to inspect / change
    
    $site2_query_string    = "parent=$site2_section_parent, publish_date<=$now, sort=publish_date";
    
    $page_template         = 'TEMPLATE';
    
    $new_page_status       = 'published';
    
    $error_msg             = '';
    
    $hrefs_file            = './hrefs_' . $date_time . '.txt';
    $hrefs_fh              = fopen($hrefs_file, "w") or die("Unable to open file.");
    
    $redirects_file        = './redirects_' . $date_time . '.txt';
    $redirects_fh          = fopen($redirects_file, "w") or die("Unable to open file.");
    
    # END OF SET UP
    ###################################################################################################
    
    # connect to primary site
    
    include("$site1_root_index_file");
    
    # connect to secondary site
    
    $site2 = new ProcessWire($site2_web_doc_root, $site2_full_domain);
    
    #..............................................................................
    # extra variable set up
    
    $image_dir          = $config->urls->files;
    
    $site1_file_dir     = $config->paths->files;
    $site2_file_dir     = $site2->config->paths->files;
    
    $site2_web_doc_root = rtrim($site2_web_doc_root, '/');
    
    $has_images_files   = 'no';
    
    #..............................................................................
    # start of script
    
    print "\nselecting SITE2 pages\n\n";
    
    $site2_results          = $site2->wire->pages->find($site2_query_string);
    
    foreach( $site2_results as $result )
          {
          $has_images_files = 'no';
    
          $site2_page_id    = $result->id;
          $site2_page_name  = $result->name;
          $site2_url        = $result->url;
          $site2_headline   = $result->headline;
          $body             = $result->body;
    
          #........................................................
          # get rewrite rule
    
          $site2_url_trimmed = ltrim($site2_url, '/');
    
          $rewrite_rule      = "RewriteRule  ^$site2_url_trimmed?$     $site1_domain" . "$site1_section_parent" . "$site2_page_name/   [L,NC,R=301]\n";
    
          fwrite($redirects_fh, $rewrite_rule);
    
          print "\n\n$rewrite_rule\n";
    
          #........................................................
          # get hrefs
    
          $dom = new DOMDocument();
          $dom->loadHTML($body);
    
          $tags = $dom->getElementsByTagName('a');
          $out  = '';
    
          foreach ($tags as $tag)
                {
                $href = $tag->getAttribute("href");
    
                if (strpos( $href, '/site/assets/files/' ) !== false)
                      {
                      continue;
                      }
    
                $out .= 'HREF: ' . $href . "\n";
                $out .= "==================================================================\n\n";
                }
    
          if ( $out != '' )
                {
                $out = "\n\n$site2_headline\n" . $out;
                fwrite($hrefs_fh, $out);
    
                print $out;
                }
    
          #........................................................
    
          if ( $stop_after_rewrites_hrefs == 'yes' )
                {
                continue;
                }
    
          #........................................................
          # add new page to site1
    
          print "\n
                 SITE2 ID: $site2_page_id
          SITE2 PAGE NAME: $site2_page_name
                SITE2 URL: $site2_url
           SITE2 HEADLINE: $site2_headline
    
          =======================================
          \n";
    
          $site1_page           = new Page();
    
          $site1_page->template = $wire->templates->get("$page_template");
    
          # check for duplicate name
    
          $check_name_dupe = $wire->pages->get( "parent=$site1_section_parent,name=$site2_page_name" );
    
          if ( $check_name_dupe->id )
                {
                $error_msg .= "
                Problem Creating Page.
                $site2_page_name exists in section: $site1_section_parent
                ==============================================================
                ";
    
                continue;
                }
    
          # save site1 page
          #........................................................
    
          $site1_page->of(false);
          $site1_page->parent = $wire->pages->get("$site1_section_parent");
          $site1_page->name   = $site2_page_name;
          $site1_page->status("$new_page_status");
          $site1_page->save();
    
          #........................................................
    
          $site1_page_id = $site1_page->id;
    
          #........................................................
          # add other fields
    
          # I thought about coding something more complex
          # that would be blind to fields and process all field types
          # as they should be processed, but it was quicker and simpler
          # to just list the fields with the code below and then copy in the
          # fields that I actually wanted to migrate.
    
          # note that my template doesn't have complex fields like repeaters, etc,
          # so I didn't need to do anything that special except with images and files.
    
          # (I placed this code at the top and ran it with an exit command.)
    
          # $template = $templates->get("$page_template");
          # foreach ( $template->fields as $f )
          #       {
          #       print "$f->name - $f->type\n";
          #       }
          # exit;
          #........................................................
          # add YOUR fields here:
    
          $site1_page->title                = $result->title;
          $site1_page->headline             = $result->headline;
    
          # ...
    
          $site1_page->save();
    
          #.........................................
          # add images
    
          if ( count($result->images) )
                {
                # the page has one or more images
    
                $has_images_files = 'yes';
    
                foreach( $result->images as $image )
                      {
                      $image_name        = $image->name;
                      $image_description = $image->description;
                      $image_url         = $image->url;
    
                      echo "$image_name\n";
                      echo "$image_url\n";
                      echo "$image_description\n";
    
                      $image_path_and_file = $site2_web_doc_root . $image_url;
    
                      $site1_page->images->add("$image_path_and_file");
    
                      # now set image description
    
                      $site1_page->images->$image_name->description = $image_description;
                      }
    
                $site1_page->save();
                }
    
          #.........................................
          # add files
    
          if ( count($result->files) )
                {
                # the page has one or more files
    
                $has_images_files = 'yes';
    
                foreach( $result->files as $file )
                      {
                      $file_name        = $file->name;
                      $file_description = $file->description;
                      $file_url         = $file->url;
    
                      echo "$file_name\n";
                      echo "$file_url\n";
                      echo "$file_description\n";
    
                      $file_path_and_file = $site2_web_doc_root . $file_url;
    
                      $site1_page->files->add("$file_path_and_file");
    
                      # now set file description
    
                      $site1_page->files->$file_name->description = $file_description;
                      }
    
                $site1_page->save();
                }
    
          #.............................................
          # prep vars
    
          $site1_page_image_dir = $site1_file_dir . $site1_page_id;
          $site2_page_image_dir = $site2_file_dir . $site2_page_id;
    
          if ( $has_images_files == 'yes' )
                {
                # replace files id with site1 id in body field
                # /site/assets/files/NUMBER/
    
                $site2_body_id_string = $image_dir . "$site2_page_id/";
                $site1_body_id_string = $image_dir . "$site1_page_id/";
    
                $body = str_replace($site2_body_id_string, $site1_body_id_string, $body);
    
                $site1_page->body     = $body;
                $site1_page->save();
    
                # copy any image variation files and chown site1 dir/files to site1 owner
    
                echo "\nCopying image variation files.\n";
    
                passthru("/bin/cp -v -n $site2_page_image_dir/* $site1_page_image_dir");
                }
          else
                {
                $site1_page->body = $body;
                $site1_page->save();
                }
    
          # we chown file dirs even if there are no images, to set the dir to the user
    
          echo "\nchowning $site1_page_image_dir to $site1_group_user\n";
    
          passthru("/bin/chown -v -R $site1_group_user $site1_page_image_dir");
    
          $site1_page->of(true);
          }
    
    print "\n\n============================================\n\n";
    
    print $error_msg;
    
    print "\n\n============================================\n\n";
    
    fclose($hrefs_fh);
    fclose($redirects_fh);
    
    print "Done!\n";
    
    exit;
    
    ###################################################################################################

     

     

    • Like 1
×
×
  • Create New...