Problems, need help? Have a tip or advice? Post it here.
14 posts Page 1 of 2
I've started to integrate the amazon api within my couch website to experiment. I've basically created a clonable template which contains items on amazon.

What i do is create an array of those items and pass that array to amazon to return all the information i need like if the item is in stock or exists etc.

What i'm getting stuck on, is when that data is returned, i'd like to update each item within couch with some information returned from the api.

So for example, if the api returns the item is out of stock, i'd want to update that particular item within couch to set it to out of stock. or if the item is in stock, update that item with the url returned from the api, and how much stock it has etc.

What i have below is a rough test which is working perfectly, and within the forearch there is some if statements, if the item has a blank amazon id, or if the amazon id doesn't exist in the returned array - if these are the cases, for now i'd like to set that item to out of stock within couch.

So i'm wondering if it's possible to use cms:db_persist to update that item within my php script, i know you can use some couch tags stuff within the php tags, but doesn't play nice with cms:db_persist.

My rough code i was looking at would be:

Code: Select all
<cms:db_persist 
_masterpage=k_template_name
_page_id=$itemId
_mode='edit'
               
amazon_status="<cms:set amazon_status='Out Of Stock' />"
/>


Which i was placing within the else parts of the if statements, but so far no luck, just errors. wondering if db_persist would be the best way to do this, or if there's another better way to accomplish this?

Maybe have to go down the route of creating my own sql and running that instead to update the database with the values i want.

Code: Select all
<cms:php>
require('../php/amazon/AmazonECS.class.php');   
$amazonEcs = new AmazonECS($api,$secret,$ext,$tag);
      
$itemArr=array(<cms:pages masterpage='store/index.php' limit='10' folder='uk' include_subfolders='1'>
array('asin'=>'<cms:show amazon_id />','pageId'=>'<cms:show k_page_id />'),
</cms:pages>
);
   
$arrAsin = array_map(function($asin) {return $asin['asin'];}, $itemArr);
      
$amzResponse = $amazonEcs->responseGroup('Small,VariationMatrix,Offers')->optionalParameters(array('Condition' => 'New'))->lookup($arrAsin);

foreach($itemArr as $item) {
   $itemId = $item['pageId'];
   $itemAsin = $item['asin'];
   $itemUrl = '';
   $itemTotalNew = '';
   $itemVariations = '';

   if(!empty($itemAsin)){
      if(in_array_r($itemAsin, $amzResponse->Items->Item)){
         echo $itemAsin . " - In Array<br>";
         foreach ($amzResponse->Items->Item as $result) {
            if($itemAsin == $result->ASIN){
               $itemUrl = $result->DetailPageURL;
               $itemTotalNew = $result->OfferSummary->TotalNew;
               $itemVariations = $result->Variations->TotalVariations;
            }
         }
         echo $itemAsin . " - <a target='_Blank' href='" . $itemUrl ."'>" . $itemAsin ."</a>" . "<br/>";
         echo "Total New:" . $itemTotalNew . " Total Variations:" . $itemVariations . "<br/>";
         echo "Page ID:" . $itemId . "<br><br>";
      }else{
         echo $itemAsin . " / ". $itemId . " - Not In Array<br><br>";
      }
   }else{
         echo $itemId . " Has Blank ASIN<br><br>";
   }
}

function in_array_r($item , $array){
   return preg_match('/"'.$item.'"/i' , json_encode($array));
}
</cms:php>


Thanks in advance for any tips/answers this lovely forum provides.
Hi,

Could you please post the full code where you tried integrating cms:db_persist within PHP but it resulted in errors? I think we should be able to make it work with some changes.

Thanks.
Hi KK,

Sure, added the code below with db_persist within, the error i'm getting is:
ERROR! ATTRIB_VALUE: Invalid first char "$"

Wondering if it has to be wrapped in something maybe?

Code: Select all
foreach($itemArr as $item) {
   $itemId = $item['pageId'];
   $itemAsin = $item['asin'];
   $itemUrl = '';
   $itemTotalNew = '';
   $itemVariations = '';

   if(!empty($itemAsin)){
      if(in_array_r($itemAsin, $amzResponse->Items->Item)){
         echo $itemAsin . " - In Array<br>";
         foreach ($amzResponse->Items->Item as $result) {
            if($itemAsin == $result->ASIN){
               $itemUrl = $result->DetailPageURL;
               $itemTotalNew = $result->OfferSummary->TotalNew;
               $itemVariations = $result->Variations->TotalVariations;
            }
         }
         echo $itemAsin . " - <a target='_Blank' href='" . $itemUrl ."'>" . $itemAsin ."</a>" . "<br/>";
         echo "Total New:" . $itemTotalNew . " Total Variations:" . $itemVariations . "<br/>";
         echo "Page ID:" . $itemId . "<br><br>";
      }else{
         echo $itemAsin . " / ". $itemId . " - Not In Array<br><br>";
         <cms:db_persist
            _masterpage=k_template_name
            _page_id=$itemId
            _mode='edit'

            amazon_url="<cms:set amazon_url='Out Of Stock' />"
         />
      }
   }else{
      echo $itemId . " Has Blank ASIN<br><br>";
      <cms:db_persist
         _masterpage=k_template_name
         _page_id=$itemId
         _mode='edit'

         amazon_url="<cms:set amazon_url='Out Of Stock' />"
      />
   }
}
Thanks.

I can see the problem. Which is - the cms:php tag executes its child tags first before executing its own code. This way it can use the children's output in its own processing.

For example, consider the following simple example -
Code: Select all
<cms:php>
    $str = "<cms:show 'hello world' />";
    echo $str;
</cms:php>

In the code above the cms:php code first executes the child cms:show tag so the final code that cms:php executes is the following -
Code: Select all
<cms:php>
    $str = "hello world";
    echo $str;
</cms:php>

I think you should be able to see the problem now. The cms:db_persist tags get executed *before* the cms:php actually gets down to work.

Anyway, there could be several ways of handling this situation.
I have to be out of my office for a while. I'll try to post a few solutions when I get back.

Thanks.
Ah ok, that makes sense, thanks for the explanation KK, i look forward to your suggestions.
Hi,

Making cms:php tag execute Couch code will require passing the code to $FUNCS->embed() function (this would be equivalent to using cms:embed in a template).

Following is a stripped-down and simplified version of your code where we create an array of page-ids and then pass each page-id from the array to cms:db_persist tag. I'm sure you'll adapt it for your real code.
Code: Select all
<cms:php>
    global $FUNCS;
   
    $itemArr=array(
        <cms:pages masterpage=k_template_name limit='10' >
            <cms:show k_page_id />,
        </cms:pages>
    );

    foreach( $itemArr as $itemId ){
       
        $tag = 'cms:db_persist';
       
        $html =<<<EOS
        <$tag
            _masterpage=k_template_name
            _page_id='$itemId'
            _mode='edit'

            my_textarea='Out Of Stockx-$itemId'
        />
EOS;

        $FUNCS->embed( $html, $is_code=1 );
        //echo $html;
    }
</cms:php>

In the code above we dynamically cobble up the cms:db_persist block of code and pass it to $FUNCS->embed().

One little quirk you'll notice above is that we are not using
Code: Select all
$html =<<<EOS
        <cms:db_persist
        ...

Instead we put the 'cms:db_persist' in a variable and then use it as
Code: Select all
        $tag = 'cms:db_persist';
       
        $html =<<<EOS
        <$tag

The reason is that in the first version, the '<cms:db_persist ..' would be a valid Couch statement and so the cms:php tag will try to execute it as its child tag before executing its own code (as we have already discussed).

You might want to comment out $FUNCS->embed() during initial testing and use the 'echo $html;' part instead to see the code being generated (will be visible in view:source of the web-page).

Hope it helps.
Hey KK,

Implemented a basic version of this within my loop like so:

Code: Select all
$html = <<<EOS
String
EOS;
echo $html;


But getting this error: Parse error: syntax error, unexpected end of file in /.../couch/tags.php(2823) : eval()'d code on line 85
I opted to use the 'heredoc' syntax of PHP (i.e. <<<EOS .. EOS) to craft the code string in my sample-
Code: Select all
        $html =<<<EOS
        <$tag
            _masterpage=k_template_name
            _page_id='$itemId'
            _mode='edit'

            my_textarea='Out Of Stockx-$itemId'
        />
EOS;

        echo $html;

It is easier to use as it does not require escaping of double-quotes in the contents. However, it has one strict requirement - the end string delimiter ('EOS' in our example) needs to be by itself on a line and in the very first column. That is, you cannot add spacing or tabs around it.
Please see https://php.net/manual/en/language.type ... ax.heredoc for details.

I think, in all probability, you are making a syntax mistake there.
Please check and let me know.

Also, if you do not want to use heredoc, feel free to use the regular method for creating strings.
Ah yeah, you were right about me having incorrect syntax, had the ending EOS; tabbed... all seems to be working now.

Many thanks for your help. Will continue to experiment with it and let you know if i run into any more trouble.
Hi KK, With your expert opinion, do you think it's wise to run that db_persist tag say 20-30 times on page load to update each item's URL and stock availability?

I plan to cache the pages eventually, but just wondering if the above would be wise.
14 posts Page 1 of 2