We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 30876 ☆ A M B ☆
    • 39 Posts
    I am working on an existing MODx evo V:1.0.4 site which has a third party JavaScript shopping cart installed.
    All works well except for the following error. I would be very grateful for any help with this.

    ISSUE: When a customer places an order they are sent a confirmation email which contains a link back to their order summary which is generated by using the code in item 1.
    When the hyperlink is clicked it calls two snippets and I believe the following error message is generated by the first snippet - see item 2.

    The code for the first [[customerDetailsInToSESSION]] snippet.- see item 3. below.


    1. Code used to generate hyperlink to existing customers order is below:
    <?php
    // get the order summary
    $orderSummary = $modx->runSnippet("checkout1ShowCartContents", array (sumariseOrder => 1));
    
    $url = str_replace($modx->config['base_url'], "", $modx->config['site_url']) . $modx->makeUrl(intval(92));
    $hash = md5($_SESSION['purchasers-details']['email']);
    $_SESSION['hash'] = $hash;
    $orderId = $_SESSION['orderId'];
    ?>
    



    2.
    *********************************
    Error message:
    « PHP Parse Error »

    PHP error debug
    Error: Invalid argument supplied for foreach()
    Error type/ Nr.: Warning - 2
    File: /var/www/vhosts/mysite.co.nz/httpdocs/manager/includes/document.parser.class.inc.php(770) : eval()'d code
    Line: 13
    ***********************************

    3. [[customerDetailsInToSESSION]] snippet
    <?php
    // [[customerDetailsInToSESSION]]
    // or
    // [[customerDetailsInToSESSION? &loginEmail=`[email protected]`]]
    
    if ( empty($_GET['customer']) && empty($loginEmail) ) return "no customer account specified";
    else {
    	$where = (!empty($loginEmail)) ? "email='" . $loginEmail . "'" : "hash='" . $_GET['customer'] . "'";
    	$db_query = $modx->db->select("id, firstName, lastName, phone, email, address1, address2, suburb, city, region, postcode, country, comments, loyaltyPoints", $modx->getFullTableName('customer_details'), $where);
    	if ($modx->db->getRecordCount($db_query) > 0) {
    		while ($row = $modx->db->getRow($db_query)) {
    		     $_SESSION['purchasers-details'] = $row;
    		}
    	}
    	else return false;
    }
    ?>
    

    This question has been answered by BobRay. See the first response.

    [ed. note: Twobears last edited this post 13 years, 8 months ago.]
      • 6038
      • 228 Posts
      The error 'Invalid argument supplied for foreach()' usually means you are not passing what you expect to pass to a foreach statement.
      It should be an array that is not empty - if its an empty array, or its not an array at all, then you get this error.
      None of the code you have supplied contains a 'foreach' statement in it - so the error must be happening somewhere else.
      Have you tried commenting out the second snippet to see if the error persists? If it does, you know it's somewhere else. If it doesn't you have to look deeper into the code.
        • 16278
        • 928 Posts
        Given there's no foreach in either snippet you've shown here, it's unlikely that the fault lies within them, since that's what the error message refers to. How about the checkout1ShowCartContents snippet? Is sumariseOrder maybe a typo for summariseOrder? Maybe that would create a bad parameter for a foreach loop there?
        ??? KP
          • 30876 ☆ A M B ☆
          • 39 Posts
          Hi and thanks for your assistance with this.

          The second snippet called (see [[orderDetailsInToSESSION]] below) has a foreach call and the error message specifies line 13 which points directly at the foreach code block in the snippet.
          I will check your other suggestions in the meantime also.
          Regarding the spelling of sumarise - the original developer of the site appears to have used the spelling mistake consistently.
          kind regards Stephen

          <?php
          // [[orderDetailsInToSESSION]]
          
          if ( empty($_GET['customer']) ) return "no customer account specified";
          else {
          	// get the details from the orderId
          	$db_query = $modx->db->select("productId, quantity", $modx->getFullTableName('customer_order_details'), "orderId='" . $_GET['orderId'] . "'");
          	if ($modx->db->getRecordCount($db_query) > 0) {
          		while ($row = $modx->db->getRow($db_query)) {
          			// get the current prices and names of the products previously ordered
          			$document_tvs = $modx->getTemplateVars(array("pagetitle", "price", "specialPrice"), "name", $row['productId']);
          			// to put the returned array into a simpler/easier to use array use the following
          			foreach ($document_tvs as $document_TV) {
          					$docTVArray[$document_TV['name']] = $document_TV['value'];
          			}
          			// put these details into the session
          		   $_SESSION['shoppingCartContents'][] = Array (
          			   'productId' => $row['productId'],
          			   'productTitle' => $docTVArray['pagetitle'],
          			   'price' => ( !empty($docTVArray['specialPrice']) ) ? $docTVArray['specialPrice'] : $docTVArray['price'],
          			   'quantity' => $row['quantity']
          		   );
          		}
          	}
          
          }
          ?>
          • discuss.answer
            • 3749
            • 24,544 Posts
            I could be wrong, but I don't think getTemplateVars() considers "pagetitle" to be a TV.

              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
              • 30876 ☆ A M B ☆
              • 39 Posts
              Hi again
              I commented out the 3 lines of the foreach statement above
              	foreach ($document_tvs as $document_TV) {
              	$docTVArray[$document_TV['name']] = $document_TV['value'];
              	}
              

              and the script ran ok with no error msg, except that it didn't produce the list of items from the order. This appears to be where the problem is, however I am unaware how to rectify the error in the code.
                • 30876 ☆ A M B ☆
                • 39 Posts
                Quote from: BobRay at Dec 18, 2012, 09:37 PM
                I could be wrong, but I don't think getTemplateVars() considers "pagetitle" to be a TV.
                Hi Bob, yes, you are right.
                Checked if pagetitle exists as a custom TV in Template Variables and it doesn't. However price and specialPrice do. pagetitle is referenced quite often in code but I can't find it as a TV, Snippet or Chunk.
                I believe the original intention was to get the product Title.
                [ed. note: Twobears last edited this post 13 years, 9 months ago.]
                  • 28042 ☆ A M B ☆
                  • 24,524 Posts
                  In my opinion, a number of things were done badly when TVs were first developed. There should have been categories for resources as well as for elements, and these "extended resource fields" should have been attached to category instead of template. TVs really have nothing at all to do with templates; in this case the template was used as a convenient way to group resources.

                  Any resource or element using any template should be able to display TVs in the front-end, either the default value or any value based on the resource ID whose TV value is desired.

                  They either should have been given a distinct tag, or else be handled more closely as an extended resource field, not a separate element altogether. Something like the way extended fields are managed for users. There is far too much confusion possible with them being a separate element, but using the same tag as resource fields.
                    Studying MODX in the desert - http://sottwell.com
                    Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                    Join the Slack Community - http://modx.org
                    • 30876 ☆ A M B ☆
                    • 39 Posts
                    <!--?php
                    // [[orderDetailsInToSESSION]]
                    
                    if ( empty($_GET['customer']) ) return "no customer account specified";
                    else {
                    	// get the details from the orderId
                    	$db_query = $modx--->db->select("productId, quantity", $modx->getFullTableName('customer_order_details'), "orderId='" . $_GET['orderId'] . "'");
                    	if ($modx->db->getRecordCount($db_query) > 0) {
                    		while ($row = $modx->db->getRow($db_query)) {
                    			// get the current prices and names of the products previously ordered
                    			$document_tvs = $modx->getTemplateVars(array("pagetitle", "price", "specialPrice"), "name", $row['productId']);
                    			// to put the returned array into a simpler/easier to use array use the following
                    			foreach ($document_tvs as $document_TV) {
                    					$docTVArray[$document_TV['name']] = $document_TV['value'];
                    			}
                    			// put these details into the session
                    		   $_SESSION['shoppingCartContents'][] = Array (
                    			   'productId' => $row['productId'],
                    			   'productTitle' => $docTVArray['pagetitle'],
                    			   'price' => ( !empty($docTVArray['specialPrice']) ) ? $docTVArray['specialPrice'] : $docTVArray['price'],
                    			   'quantity' => $row['quantity']
                    		   );
                    		}
                    	}
                    
                    }
                    ?>


                    It appears that the original developers intention was to get the [[*pagetitle]] tag into the array where the "pagetitle" TV is called.
                    Is it possible to retrieve the value of the [[*pagetitle]] tag into a "pagetitle" TV or is there a more elegant method of achieving this?
                    (I'm still a bit of a novice here) [ed. note: Twobears last edited this post 13 years, 9 months ago.]