ここの情報は古いです。ご理解頂いた上でお取り扱いください。

source: OpenPNE_specification/patch/OpenPNE_2_12_12_to_OpenPNE_2_12_13.patch @ 12293

Last change on this file since 12293 was 12293, checked in by kiwa, 11 years ago

patch OpenPNE2.12.12 to OpenPNE2.12.13

File size: 94.6 KB
  • setup/OpenPNE_Setup.html

     
    231231        他人に推測されにくい文字列にしてください。</dd>
    232232<dt>MAIL_SERVER_DOMAIN</dt>
    233233        <dd>メールサーバのドメイン名(携帯版でメール投稿をする場合に使います)</dd>
     234<dt>AMAZON_ACCESS_KEY_ID</dt>
     235        <dd>Amazon Web Service 公開アクセスキー(レビューの投稿に使用します)<br>
     236        詳細はこちらをご覧下さい。 Amazon Product Advertising API <a href="https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html" target="_blank">https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html</a></dd>
     237<dt>AMAZON_SECRET_ACCESS_KEY</dt>
     238        <dd>Amazon Web Service 秘密キー(レビューの投稿に使用します)<br>
     239        詳細はこちらをご覧下さい。 Amazon Product Advertising API <a href="https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html" target="_blank">https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html</a></dd>
    234240</dl>
    235241
    236242<p>必要に応じて、その他の設定も書き換えてください。
  • setup/OpenPNE_Setup_pgsql.html

     
    235235        他人に推測されにくい文字列にしてください。</dd>
    236236<dt>MAIL_SERVER_DOMAIN</dt>
    237237        <dd>メールサーバのドメイン名(携帯版でメール投稿をする場合に使います)</dd>
     238<dt>AMAZON_ACCESS_KEY_ID</dt>
     239        <dd>Amazon Web Service 公開アクセスキー(レビューの投稿に使用します)<br>
     240        詳細はこちらをご覧下さい。 Amazon Product Advertising API <a href="https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html" target="_blank">https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html</a></dd>
     241<dt>AMAZON_SECRET_ACCESS_KEY</dt>
     242        <dd>Amazon Web Service 秘密キー(レビューの投稿に使用します)<br>
     243        詳細はこちらをご覧下さい。 Amazon Product Advertising API <a href="https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html" target="_blank">https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html</a></dd>
    238244</dl>
    239245
    240246<p>必要に応じて、その他の設定も書き換えてください。
  • lib/include/Services/AmazonECS4.php

     
    3535* @category  Web Services
    3636* @package   Services_Amazon
    3737* @author    John Downey <jdowney@gmail.com>
    38 * @author    Tatsuya Tsuruoka <ttsuruoka@p4life.jp>
     38* @author    Tatsuya Tsuruoka <tatsuya.tsuruoka@gmail.com>
    3939* @copyright 2004 John Downey
    4040* @license   http://www.freebsd.org/copyright/freebsd-license.html 2 Clause BSD License
    41 * @version   CVS: $Id: AmazonECS4.php,v 1.4 2006/08/04 10:31:00 ttsuruoka Exp $
     41* @version   CVS: $Id: AmazonECS4.php,v 1.9 2008/04/02 04:23:38 ttsuruoka Exp $
    4242* @link      http://pear.php.net/package/Services_Amazon/
    4343* @filesource
    4444*/
    4545
    4646/**
     47 * NOTICE:
     48 * This class is for backward compatibility and should be considered obsolete.
     49 * After August 15, 2009, all requests without a signature will be denied.
     50 * You may as well use Services_Amazon when you create a new application.
     51 */
     52
     53/**
    4754* Uses PEAR class for error management
    4855*/
    4956require_once 'PEAR.php';
     
    9198*
    9299* @package Services_Amazon
    93100* @author  John Downey <jdowney@gmail.com>
    94 * @author  Tatsuya Tsuruoka <ttsuruoka@p4life.jp>
     101* @author  Tatsuya Tsuruoka <tatsuya.tsuruoka@gmail.com>
    95102* @access  public
    96 * @version Release: 0.7.1
     103* @version Release: 0.8.0
    97104* @uses    PEAR
    98105* @uses    HTTP_Request
    99106* @uses    XML_Unserializer
     
    240247    */
    241248    function getApiVersion()
    242249    {
    243         return '0.7.1';
     250        return '0.8.0';
    244251    }
    245252
    246253    /**
     
    888895    function TransactionLookup($transaction_id, $options = array())
    889896    {
    890897        $params = $options;
    891         $params['Operation'] = 'SimilarityLookup';
     898        $params['Operation'] = 'TransactionLookup';
    892899        $params['TransactionId'] = $transaction_id;
    893900        return $this->_sendRequest($params);
    894901    }
  • lib/include/Services/Amazon.php

     
    11<?php
    22/* vim: set expandtab tabstop=4 shiftwidth=4: */
    33/**
    4 * Implementation of a developers backend for accessing Amazon.com's retail and
    5 * assosciate services.
    6 *
    7 * PHP versions 4 and 5
    8 *
    9 * LICENSE: Copyright 2004 John Downey. All rights reserved.
    10 *
    11 * Redistribution and use in source and binary forms, with or without
    12 * modification, are permitted provided that the following conditions are met:
    13 *
    14 * o Redistributions of source code must retain the above copyright notice, this
    15 *   list of conditions and the following disclaimer.
    16 * o Redistributions in binary form must reproduce the above copyright notice,
    17 *   this list of conditions and the following disclaimer in the documentation
    18 *   and/or other materials provided with the distribution.
    19 *
    20 * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT "AS IS" AND ANY EXPRESS OR
    21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    23 * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    30 *
    31 * The views and conclusions contained in the software and documentation are
    32 * those of the authors and should not be interpreted as representing official
    33 * policies, either expressed or implied, of The PEAR Group.
    34 *
    35 * @category  Web Services
    36 * @package   Services_Amazon
    37 * @author    John Downey <jdowney@gmail.com>
    38 * @author    Tatsuya Tsuruoka <ttsuruoka@p4life.jp>
    39 * @copyright 2004 John Downey
    40 * @license   http://www.freebsd.org/copyright/freebsd-license.html 2 Clause BSD License
    41 * @version   CVS: $Id: Amazon.php,v 1.2 2006/01/27 16:29:20 ttsuruoka Exp $
    42 * @link      http://pear.php.net/package/Services_Amazon/
    43 * @filesource
    44 */
     4 * PHP interface to Amazon Product Advertising API
     5 *
     6 * PHP versions 4 and 5
     7 *
     8 * LICENSE: Copyright 2004-2009 John Downey. All rights reserved.
     9 *
     10 * Redistribution and use in source and binary forms, with or without
     11 * modification, are permitted provided that the following conditions are met:
     12 *
     13 * o Redistributions of source code must retain the above copyright notice, this
     14 *   list of conditions and the following disclaimer.
     15 * o Redistributions in binary form must reproduce the above copyright notice,
     16 *   this list of conditions and the following disclaimer in the documentation
     17 *   and/or other materials provided with the distribution.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT "AS IS" AND ANY EXPRESS OR
     20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     22 * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 *
     30 * The views and conclusions contained in the software and documentation are
     31 * those of the authors and should not be interpreted as representing official
     32 * policies, either expressed or implied, of The PEAR Group.
     33 *
     34 * @category  Web Services
     35 * @package   Services_Amazon
     36 * @author    John Downey <jdowney@gmail.com>
     37 * @author    Tatsuya Tsuruoka <tatsuya.tsuruoka@gmail.com>
     38 * @copyright 2004-2009 John Downey
     39 * @license   http://www.freebsd.org/copyright/freebsd-license.html 2 Clause BSD License
     40 * @version   CVS: $Id: Amazon.php,v 1.4 2007/12/16 17:27:44 ttsuruoka Exp $
     41 * @link      http://pear.php.net/package/Services_Amazon/
     42 * @filesource
     43 */
    4544
    46 // This class is for backward compatibility and should be considered obsolete.
    47 // You may as well use Services_AmazonECS4 when you create a new application.
    48 
    4945/**
    50 * Uses PEAR class for error management.
    51 */
     46 * Uses PEAR class for error management.
     47 */
    5248require_once 'PEAR.php';
    5349
    5450/**
    55 * Uses HTTP_Request class to send and receive data from Amazon web servers.
    56 */
     51 * Uses HTTP_Request class to send and receive data from Amazon web servers.
     52 */
    5753require_once 'HTTP/Request.php';
    5854
    5955/**
    60 * Uses XML_Unserializer class to parse data received from Amazon.
    61 */
     56 * Uses XML_Unserializer class to parse data received from Amazon.
     57 */
    6258require_once 'XML/Unserializer.php';
    6359
    6460/**
    65 * Class for accessing and retrieving information from Amazon's Web Services.
    66 *
    67 * @package Services_Amazon
    68 * @author  John Downey <jdowney@gmail.com>
    69 * @author  Tatsuya Tsuruoka <ttsuruoka@p4life.jp>
    70 * @access  public
    71 * @version Release: 0.7.1
    72 * @uses    PEAR
    73 * @uses    HTTP_Request
    74 * @uses    XML_Unserializer
    75 */
     61 * A default base URL that is specific to the locale
     62 *
     63 * Locale    Endpoint
     64 * ----------------------------------------------
     65 * CA        http://ecs.amazonaws.ca/onca/xml
     66 *           https://aws.amazonaws.ca/onca/xml
     67 * DE        http://ecs.amazonaws.de/onca/xml
     68 *           https://aws.amazonaws.de/onca/xml
     69 * FR        http://ecs.amazonaws.fr/onca/xml
     70 *           https://aws.amazonaws.fr/onca/xml
     71 * JP        http://ecs.amazonaws.jp/onca/xml
     72 *           https://aws.amazonaws.jp/onca/xml
     73 * UK        http://ecs.amazonaws.co.uk/onca/xml
     74 *           https://aws.amazonaws.co.uk/onca/xml
     75 * US        http://ecs.amazonaws.com/onca/xml
     76 *           https://aws.amazonaws.com/onca/xml
     77 */
     78if (!defined('SERVICES_AMAZON_BASEURL')) {
     79    define('SERVICES_AMAZON_BASEURL', 'http://ecs.amazonaws.com/onca/xml');
     80}
     81
     82/**
     83 * An API version
     84 *
     85 * Use this to retrieve a particular version of the Product Advertising API.
     86 */
     87if (!defined('SERVICES_AMAZON_ECSVERSION')) {
     88    define('SERVICES_AMAZON_ECSVERSION', '2009-03-31');
     89}
     90
     91/**
     92 * Class for accessing and retrieving information from Amazon's Web Services
     93 *
     94 * @package Services_Amazon
     95 * @author  John Downey <jdowney@gmail.com>
     96 * @author  Tatsuya Tsuruoka <tatsuya.tsuruoka@gmail.com>
     97 * @access  public
     98 * @version Release: 0.8.0
     99 * @uses    PEAR
     100 * @uses    HTTP_Request
     101 * @uses    XML_Unserializer
     102 */
    76103class Services_Amazon
    77104{
    78105    /**
    79     * The developers token used when quering Amazon servers.
    80     *
    81     * @access private
    82     * @var    string $_token
    83     */
    84     var $_token = null;
    85    
     106     * An Amazon Access Key ID used when quering Amazon servers
     107     *
     108     * @access private
     109     * @var    string
     110     */
     111    var $_access_key_id = null;
     112
    86113    /**
    87     * An Amazon Associate ID used in the URL's so a commision may be payed.
    88     *
    89     * @access private
    90     * @var    string $_affid
    91     */
    92     var $_affid = null;
    93    
     114     * An Amazon Secret Access Key used when quering Amazon servers
     115     *
     116     * @access private
     117     * @var    string
     118     */
     119    var $_secret_access_key = null;
     120
    94121    /**
    95     * The locale to pass to Amazon.com's servers.
    96     *
    97     * @access private
    98     * @var    string $_locale
    99     */   
    100     var $_locale = null;
    101    
     122     * An Amazon Associate Tag used in the URL's so a commision may be payed
     123     *
     124     * @access private
     125     * @var    string
     126     */
     127    var $_associate_tag = null;
     128
    102129    /**
    103     * The base url used to build the query for the Amazon servers.
    104     *
    105     * @access private
    106     * @var    string $_baseurl
    107     */
    108     var $_baseurl = null;
     130     * A base URL used to build the query for the Amazon servers
     131     *
     132     * @access private
     133     * @var    string
     134     */
     135    var $_baseurl = SERVICES_AMAZON_BASEURL;
    109136
    110137    /**
    111     * Constructor
    112     *
    113     * @access public
    114     * @param  string $token The developers token used when quering Amazon servers.
    115     * @param  string $affid An Amazon Associate ID used in the URL's so a commision may be payed.
    116     * @see    setToken
    117     * @see    setAssociateID
    118     * @see    setBaseUrl
    119     * @see    setLocale
    120     */
    121     function Services_Amazon($token = null, $affid = null, $locale = 'us', $baseurl = 'http://webservices.amazon.com/onca/xml2') {
    122         if (!is_null($token)) {
    123             $this->_token = $token;
    124         }
     138     * A service version
     139     *
     140     * @access private
     141     * @var    string
     142     */
     143    var $_version = SERVICES_AMAZON_ECSVERSION;
    125144
    126         if (!is_null($affid)) {
    127             $this->_affid = $affid;
    128         }
    129        
    130         $this->_baseurl = $baseurl;
    131         $this->setLocale($locale);
     145    /**
     146     * The time that the Amazon took to process the request
     147     *
     148     * @access private
     149     * @var    string
     150     */
     151    var $_processing_time = null;
     152
     153    /**
     154     * The last URL accessed to the Amazon (for debugging)
     155     *
     156     * @access private
     157     * @var    string
     158     */
     159    var $_lasturl = null;
     160
     161    /**
     162     * The raw result returned from the request
     163     *
     164     * @access private
     165     * @var    string
     166     */
     167    var $_raw_result = null;
     168
     169    /**
     170     * The cache object
     171     *
     172     * @access private
     173     * @var    object
     174     */
     175    var $_cache = null;
     176
     177    /**
     178     * The cache expire time
     179     *
     180     * Defaults to one hour.
     181     *
     182     * @access private
     183     * @var    integer
     184     */
     185    var $_cache_expire = 3600;
     186
     187    /**
     188     * Proxy server
     189     *
     190     * @access private
     191     * @var    string
     192     */
     193    var $_proxy_host = null;
     194
     195    /**
     196     * Proxy port
     197     *
     198     * @access private
     199     * @var    integer
     200     */
     201    var $_proxy_port = null;
     202
     203    /**
     204     * Proxy username
     205     *
     206     * @access private
     207     * @var    string
     208     */
     209    var $_proxy_user = null;
     210
     211    /**
     212     * Proxy password
     213     *
     214     * @access private
     215     * @var    string
     216     */
     217    var $_proxy_pass = null;
     218
     219    /**
     220     * Timestamp (for debugging)
     221     *
     222     * @access private
     223     * @var    integer
     224     */
     225    var $_timestamp = null;
     226
     227    /**
     228     * Errors
     229     *
     230     * @access private
     231     * @var    array
     232     */
     233    var $_errors = array();
     234
     235    /**
     236     * Constructor
     237     *
     238     * @access public
     239     * @param  string $access_key_id An Amazon Access Key ID used when quering Amazon servers
     240     * @param  string $secret_access_key An Amazon Secret Access Key used when quering Amazon servers
     241     * @param  string $associate_tag An Amazon Associate Tag used in the URL's so a commision may be payed
     242     * @see    setAccessKeyID
     243     * @see    setSecretAccessKey
     244     * @see    setAssociateTag
     245     * @see    setBaseUrl
     246     * @see    setVersion
     247     */
     248    function Services_Amazon($access_key_id, $secret_access_key, $associate_tag = null)
     249    {
     250        $this->setAccessKeyID($access_key_id);
     251        $this->setSecretAccessKey($secret_access_key);
     252        $this->setAssociateTag($associate_tag);
    132253    }
    133254
    134255    /**
    135     * Retrieves the current version of this classes API.
    136     *
    137     * All major versions are backwards compatible with older version of the same
    138     * version number. Such as 1.5 would work for a script written to use 1.0.
    139     * However on the filp side a script that needs 1.5 would not work with
    140     * API version 1.0.
    141     *
    142     * @access public
    143     * @static
    144     * @return string the API version
    145     */
    146     function getApiVersion() {
    147         return '1.0';
     256     * Retrieves the current version of this classes API
     257     *
     258     * @access public
     259     * @static
     260     * @return string The API version
     261     */
     262    function getApiVersion()
     263    {
     264        return '0.8.0';
    148265    }
    149266
    150267    /**
    151     * Retrieves the currently set Developer token.
    152     *
    153     * To use Amazon's Web Services you need a developer's token. Visit
    154     * {@link http://www.amazon.com/webservices} and read their license
    155     * agreement to recieve a free token.
    156     *
    157     * @access public
    158     * @return string the currently set Developer token
    159     * @see    setToken()
    160     */
    161     function getToken() {
    162         return $this->_token;
     268     * Sets an Access Key ID
     269     *
     270     * @access public
     271     * @param  string $access_key_id An Access Key ID
     272     * @return void
     273     */
     274    function setAccessKeyID($access_key_id)
     275    {
     276        $this->_access_key_id = $access_key_id;
    163277    }
    164278
    165279    /**
    166     * Sets the Developer token to use when quering Amazon's Web Services.
    167     *
    168     * @access public
    169     * @param  string $token your Developer token
    170     * @return void
    171     * @see    getToken()
    172     */
    173     function setToken($token) {
    174         $this->_token = $token;
     280     * Sets a Subscription ID (for backward compatibility)
     281     *
     282     * @access public
     283     * @param  string $subid A Subscription ID
     284     * @return void
     285     */
     286    function setSubscriptionID($subid)
     287    {
     288        $this->setAccessKeyID($subid);
    175289    }
    176290
    177291    /**
    178     * Retrieves the currently set Associate ID.
    179     *
    180     * Your Associate ID is used to built the links to amazon which will give
    181     * you credit for the sale. Visit {@link http://associates.amazon.com} to
    182     * sign up for an Associate ID.
    183     *
    184     * @access public
    185     * @return string the currently set Associate ID.
    186     * @see    setAssociateID()
    187     */
    188     function getAssociateID() {
    189         return $this->_affid;
     292     * Sets a Secret Access Key
     293     *
     294     * @access public
     295     * @param  string $subid A Secret Access Key
     296     * @return void
     297     */
     298    function setSecretAccessKey($secret_access_key)
     299    {
     300        $this->_secret_access_key = $secret_access_key;
    190301    }
    191302
    192303    /**
    193     * Sets the Associate ID to use when building links to Amazon.com.
    194     *
    195     * @access public
    196     * @param  string $affid your Associate ID
    197     * @return void
    198     * @see    getAssociateID()
    199     */
    200     function setAssociateID($affid) {
    201         $this->_affid = $affid;
     304     * Sets an Associate Tag
     305     *
     306     * @access public
     307     * @param  string $associate_tag An Associate Tag
     308     * @return void
     309     */
     310    function setAssociateTag($associate_tag)
     311    {
     312        $this->_associate_tag = $associate_tag;
    202313    }
    203    
    204314    /**
    205     * Retrieves the currently set base url.
    206     *
    207     * @access public
    208     * @return string the currently set base url
    209     * @see    setBaseUrl()
    210     */
    211     function getBaseUrl() {
    212         return $this->_baseurl;
     315     * Sets an Associate ID
     316     *
     317     * @access public
     318     * @param  string $associd An Associate ID
     319     * @return void
     320     */
     321    function setAssociateID($associd)
     322    {
     323        $this->setAssociateTag($associd);
    213324    }
    214325
    215326    /**
    216     * Sets the base url used when making a query to Amazon.com.
    217     *
    218     * @access public
    219     * @param  string $baseurl the base url to use
    220     * @return void
    221     * @see    getBaseUrl()
    222     */
    223     function setBaseUrl($baseurl) {
    224         $this->_baseurl = $baseurl;
     327     * Sets the base URL
     328     *
     329     * @access public
     330     * @param  string $url The base url
     331     * @return void
     332     */
     333    function setBaseUrl($url)
     334    {
     335        $this->_baseurl = $url;
    225336    }
    226    
     337
    227338    /**
    228     * Retrieves the locale passed when making a query to Amazon.com.
    229     *
    230     * @access public
    231     * @return string the currently set locale
    232     * @see    setLocale()
    233     */   
    234     function getLocale() {
    235         return $this->_locale;
    236     }
    237    
    238     /**
    239     * Sets the locale passed when making a query to Amazon.
    240     *
    241     * Currently only us, uk, de, jp, fr and ca are supported by Amazon.
    242     *
    243     * @access public
    244     * @param  string $locale the new locale to use
    245     * @return void
    246     * @see    getLocale()
    247     */   
    248     function setLocale($locale) {
     339     * Sets the locale passed when making a query to Amazon
     340     *
     341     * Currently US, UK, DE, JP, FR, and CA are supported
     342     *
     343     * @access public
     344     * @param  string $locale The new locale to use
     345     * @return mixed A PEAR_Error on error, a true on success
     346     */
     347    function setLocale($locale)
     348    {
    249349        $urls = array(
    250             'us' => 'http://webservices.amazon.com/onca/xml2',
    251             'uk' => 'http://webservices.amazon.co.uk/onca/xml2',
    252             'de' => 'http://webservices.amazon.de/onca/xml2',
    253             'jp' => 'http://webservices.amazon.co.jp/onca/xml2',
    254             'fr' => 'http://webservices.amazon.fr/onca/xml2',
    255             'ca' => 'http://webservices.amazon.ca/onca/xml2',
     350            'US' => 'http://ecs.amazonaws.com/onca/xml',
     351            'UK' => 'http://ecs.amazonaws.co.uk/onca/xml',
     352            'DE' => 'http://ecs.amazonaws.de/onca/xml',
     353            'JP' => 'http://ecs.amazonaws.jp/onca/xml',
     354            'FR' => 'http://ecs.amazonaws.fr/onca/xml',
     355            'CA' => 'http://ecs.amazonaws.ca/onca/xml',
    256356        );
    257         $this->_locale = strtolower($locale);
     357        $locale = strtoupper($locale);
    258358        if (empty($urls[$locale])) {
    259             return;
     359            return PEAR::raiseError('Invalid locale');
    260360        }
    261361        $this->setBaseUrl($urls[$locale]);
     362        return true;
    262363    }
     364
     365    /**
     366     * Sets a version
     367     *
     368     * @access public
     369     * @param  string $version A service version
     370     * @return void
     371     */
     372    function setVersion($version)
     373    {
     374        $this->_version = $version;
     375    }
     376
     377    /**
     378     * Enables caching the data
     379     *
     380     * Requires Cache to be installed.
     381     * Example:
     382     * <code>
     383     * <?php
     384     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     385     * $amazon->setCache('file', array('cache_dir' => 'cache/'));
     386     * $amazon->setCacheExpire(86400); // 86400 seconds = 24 hours
     387     * $result = $amazon->BrowseNodeLookup('283155');
     388     * ?>
     389     * </code>
     390     *
     391     * @access public
     392     * @param  string $container Name of container class
     393     * @param  array $container_options Array with container class options
     394     * @return mixed A PEAR_Error on error, a true on success
     395     * @see    setCacheExpire()
     396     */
     397    function setCache($container = 'file', $container_options = array())
     398    {
     399        if(!class_exists('Cache')){
     400            @include_once 'Cache.php';
     401        }
     402       
     403        @$cache = new Cache($container, $container_options);
     404       
     405        if (is_object($cache)) {
     406            $this->_cache = $cache;
     407        } else {
     408            $this->_cache = null;
     409            return PEAR::raiseError('Cache init failed');
     410        }
     411
     412        return true;
     413    }
    263414   
    264415    /**
    265     * Retrieves an array of modes supported by Amazon.
    266     *
    267     * The array is arranged with the shorthand version as the key and the human
    268     * readable version as its value. Below are the current modes in the list.
    269     * <pre>
    270     * baby        - Baby
    271     * books       - Books
    272     * classical   - Classical Music
    273     * dvd         - DVD
    274     * electronics - Electronics
    275     * garden      - Outdoor Living
    276     * kitchen     - Kitchen & Housewares
    277     * magazines   - Magazines
    278     * music       - Popular Music
    279     * pc-hardware - Computers
    280     * photo       - Camera & Photo
    281     * software    - Software
    282     * toys        - Toys & Games
    283     * universal   - Tools & Hardware
    284     * vhs         - VHS
    285     * videogames  - Computer & Video Games
    286     * </pre>
    287     *
    288     * @access public
    289     * @static
    290     * @return array An array of modes with the short hand modename to pass to
    291     *               Amazon as the key and the longer human readable form as the
    292     *               key's value.
    293     */
    294     function getModes() {
    295         return array('baby'        => 'Baby',
    296                      'books'       => 'Books',
    297                      'classical'   => 'Classical Music',
    298                      'dvd'         => 'DVD',
    299                      'electronics' => 'Electronics',
    300                      'garden'      => 'Outdoor Living',
    301                      'kitchen'     => 'Kitchen & Housewares',
    302                      'magazines'   => 'Magazines',
    303                      'music'       => 'Popular Music',
    304                      'pc-hardware' => 'Computers',
    305                      'photo'       => 'Camera & Photo',
    306                      'software'    => 'Software',
    307                      'toys'        => 'Toys & Games',
    308                      'universal'   => 'Tools & Hardware',
    309                      'vhs'         => 'VHS',
    310                      'videogames'  => 'Computer & Video Games');
     416     * Sets cache expire time
     417     *
     418     * Amazon dictates that any prices that are displayed that may be over an
     419     * hour old should be accompanied by some sort of timestamp. You can get
     420     * around that by expiring any queries that use the time in an hour (3600
     421     * seconds).
     422     *
     423     * @access public
     424     * @param  integer $secs Expire time in seconds
     425     * @return void
     426     * @see    setCache()
     427     */
     428    function setCacheExpire($secs)
     429    {
     430        $this->_cache_expire = $secs;
    311431    }
    312432
    313433    /**
    314     * Retrives the information of a product given its unique ASIN code.
    315     *
    316     * Amazon Standard Identification Numbers (ASINs) are unique blocks of 10
    317     * letters and/or numbers that identify items. You can find the ASIN on the
    318     * item's product information page at Amazon.com.
    319     *
    320     * Example:
    321     * <code>
    322     * <?php
    323     * require_once 'PEAR.php';
    324     * require_once 'Services/Amazon.php';
    325     *
    326     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    327     * $products = $amazon->searchAsin('0672325616');
    328     *
    329     * if(!PEAR::isError($products)) {
    330     *     var_dump($products);
    331     * } else {
    332     *     echo $products->message;
    333     * }
    334     * ?>
    335     * </code>
    336     * If you were to fill in the Developer token in the constructor this would
    337     * return the results for George Schlossnagle's book Advanced PHP
    338     * Programming.
    339     *
    340     * @access public
    341     * @param  string $asin The Amazon Standard Identification Number (ASIN)
    342     *                      of the product your searching for
    343     * @return array The array of products retrieved by the query.
    344     */
    345     function searchAsin($asin) {
    346         return $this->_sendRequest(array('AsinSearch' => $asin), 1);
     434     * Sets a proxy
     435     *
     436     * @access public
     437     * @param string $host Proxy host
     438     * @param int $port Proxy port
     439     * @param string $user Proxy username
     440     * @param string $pass Proxy password
     441     */
     442    function setProxy($host, $port = 8080, $user = null, $pass = null)
     443    {
     444        $this->_proxy_host = $host;
     445        $this->_proxy_port = $port;
     446        $this->_proxy_user = $user;
     447        $this->_proxy_pass = $pass;
    347448    }
    348449
    349450    /**
    350     * Retrives the information of a book given its unique ISBN number.
    351     *
    352     * International Standard Book Numbers (ISBNs) are unique numbers that
    353     * identify every book that is published. It is generally located below a
    354     * barcode on the back of the book. Note: ISBN numbers are synonymous with
    355     * ASIN numbers as Amazon uses the ISBN for a books ASIN.
    356     *
    357     * @access public
    358     * @param  string $isbn The International Standard Book Number (ISBN) of the
    359     *                      book you are searching for.
    360     * @return array The array of products retrieved by the query.
    361     * @see    searchAsin()
    362     */
    363     function searchIsbn($isbn) {
    364         return $this->searchAsin($isbn, 1);
     451     * Sets a timestamp (for debugging)
     452     *
     453     * @access public
     454     * @param integer $time A timestamp
     455     */
     456    function setTimestamp($time)
     457    {
     458        $this->_timestamp = $time;
    365459    }
    366    
     460
    367461    /**
    368     * Retrives the information of a product given its unique UPC number.
    369     *
    370     * Since Amazon usually carries the latest version of a product it may not
    371     * be possible to find a product given its UPC even though a later version
    372     * appears on Amazon.com.
    373     *
    374     * @access public
    375     * @param  string $upc Universal Product Code (UPC) for the product you are
    376     *                     searching for.
    377     * @return array The array of products retrieved by the query.
    378     */
    379     function searchUpc($upc) {
    380         return $this->_sendRequest(array('UpcSearch' => $upc), 1);
     462     * Retrieves all error codes and messages
     463     *
     464     * <code>
     465     * if (PEAR::isError($result)) {
     466     *     foreach ($amazon->getErrors() as $error) {
     467     *         echo $error['Code'];
     468     *         echo $error['Message'];
     469     *     }
     470     * }
     471     * </code>
     472     *
     473     * @access public
     474     * @return array All errors
     475     */
     476    function getErrors()
     477    {
     478        return $this->_errors;
    381479    }
    382480   
    383481    /**
    384     * Searches Amazon.com for a specific keyword.
    385     *
    386     * To limit your search to just a specific category such as books then set
    387     * the $mode param to something other then null. See {@link getModes()} for a list of
    388     * modes.
    389     *
    390     * Example:
    391     * <code>
    392     * <?php
    393     * require_once 'PEAR.php';
    394     * require_once 'Services/Amazon.php';
    395     *
    396     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    397     * $products = $amazon->searchKeyword('PHP');
    398     *
    399     * if(!PEAR::isError($products)) {
    400     *    var_dump($products);
    401     * } else {
    402     *    echo $products->message;
    403     * }
    404     * ?>
    405     * </code>
    406     * If you were to fill in the Developer token in the constructor this would
    407     * search Amazon.com for all books about PHP and return the first 10 results.
    408     * To retrieve more results you would pass a page number.
    409     *
    410     * @access public
    411     * @param  string $keyword The keyword to search for.
    412     * @param  string $mode The section of the site you wish to search in.
    413     *                      Defaults to music.
    414     * @param  interger $page Which page of products to retrieve. Defaults to
    415     *                        the first.
    416     * @return array The array of products retrieved by the query.
    417     * @see    getModes()
    418     */
    419     function searchKeyword($keyword, $mode = null, $page = 1) {
    420         return $this->_sendRequest(array('KeywordSearch' => $keyword, 'mode' => $mode), $page);
     482     * Retrieves the error code and message
     483     *
     484     * <code>
     485     * if (PEAR::isError($result)) {
     486     *     $error = $amazon->getError();
     487     *     echo $error['Code'];
     488     *     echo $error['Message'];
     489     * }
     490     * </code>
     491     *
     492     * @access public
     493     * @return array All errors
     494     */
     495    function getError()
     496    {
     497        return current($this->_errors);
    421498    }
    422499
    423500    /**
    424     * Searches Amazon for products similer to the Asin passed to it.
    425     *
    426     * To limit your search to just a specific category such as books then set
    427     * the $mode param to something other then null. See {@link getModes()} for a list of
    428     * modes. If the $mode param is null it will search all modes.
    429     *
    430     * Example:
    431     * <code>
    432     * <?php
    433     * require_once 'PEAR.php';
    434     * require_once 'Services/Amazon.php';
    435     *
    436     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    437     * $products = $amazon->searchSimilar('0672325616', 'books');
    438     *
    439     * if(!PEAR::isError($products)) {
    440     *    var_dump($products);
    441     * } else {
    442     *    echo $products->message;
    443     * }
    444     * ?>
    445     * </code>
    446     * If you were to fill in the Developer token in the constructor this would
    447     * search Amazon.com for all books related to George Schlossnagle's book
    448     * Advanced PHP Programming. To retrieve more results you would pass a page
    449     * number.
    450     *
    451     * @access public
    452     * @param  string $asin The Asin of the product that is similer to what you
    453     *                      are searching for.
    454     * @param  string $mode The section of the site you wish to search in
    455     * @param  interger $page Which page of products to retrieve. Defaults to
    456     *                        the first.
    457     * @return array The array of products retrieved by the query.
    458     * @see    getModes()
    459     */
    460     function searchSimilar($asin, $mode = null, $page = 1) {
    461         return $this->_sendRequest(array('SimilaritySearch' => $asin, 'mode' => $mode), $page);
     501     * Retrieves the processing time
     502     *
     503     * @access public
     504     * @return string Processing time
     505     */
     506    function getProcessingTime()
     507    {
     508        return $this->_processing_time;
    462509    }
    463510
    464511    /**
    465     * Searches Amazon.com for a specific author.
    466     *
    467     * Example:
    468     * <code>
    469     * <?php
    470     * require_once 'PEAR.php';
    471     * require_once 'Services/Amazon.php';
    472     *
    473     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    474     * $products = $amazon->searchAuthor('Frank Herbert');
    475     *
    476     * if(!PEAR::isError($products)) {
    477     *    var_dump($products);
    478     * } else {
    479     *    echo $products->message;
    480     * }
    481     * ?>
    482     * </code>
    483     * If you were to fill in the Developer token in the constructor this would
    484     * search Amazon.com for all books written by the great American author
    485     * Frank Herbert.
    486     *
    487     * @access public
    488     * @param  string $author The author you are searching for.
    489     * @param  interger $page Which page of products to retrieve. Defaults to
    490     *                        the first.
    491     * @return array The array of products retrieved by the query.
    492     */
    493     function searchAuthor($author, $page = 1) {
    494         return $this->_sendRequest(array('AuthorSearch' => $author, 'mode' => 'books'), $page);
     512     * Retrieves the last URL accessed to the Amazon (for debugging)
     513     *
     514     * @access public
     515     * @return string The Last URL
     516     */
     517    function getLastUrl()
     518    {
     519        return $this->_lasturl;
    495520    }
    496521
    497522    /**
    498     * Searches Amazon for music by a specified artist.
    499     *
    500     * Example:
    501     * <code>
    502     * <?php
    503     * require_once 'PEAR.php';
    504     * require_once 'Services/Amazon.php';
    505     *
    506     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    507     * $products = $amazon->searchArtist('Dream Theater');
    508     *
    509     * if(!PEAR::isError($products)) {
    510     *    var_dump($products);
    511     * } else {
    512     *    echo $products->message;
    513     * }
    514     * ?>
    515     * </code>
    516     * If you were to fill in the Developer token in the constructor this would
    517     * search Amazon.com for music by American Progressive Metal band Dream
    518     * Theater.
    519     *
    520     * @access public
    521     * @param  string $artist The artist you are searching for.
    522     * @param  interger $page Which page of products to retrieve. Defaults to
    523     *                        the first.
    524     * @return array The array of products retrieved by the query.
    525     */
    526     function searchArtist($artist, $page = 1) {
    527         return $this->_sendRequest(array('ArtistSearch' => $artist, 'mode' => 'music'), $page);
     523      * Retrieves the raw result
     524      *
     525      * @access public
     526      * @return string The raw result
     527      */
     528    function getRawResult()
     529    {
     530        return $this->_raw_result;
    528531    }
    529532
    530533    /**
    531     * Searches Amazon for movies that portrays a specific actor.
    532     *
    533     * Example:
    534     * <code>
    535     * <?php
    536     * require_once 'PEAR.php';
    537     * require_once 'Services/Amazon.php';
    538     *
    539     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    540     * $products = $amazon->searchActor('Samuel L. Jackson');
    541     *
    542     * if(!PEAR::isError($products)) {
    543     *    var_dump($products);
    544     * } else {
    545     *    echo $products->message;
    546     * }
    547     * ?>
    548     * </code>
    549     * If you were to fill in the Developer token in the constructor this would
    550     * search Amazon.com for DVD movies portraying the American Actor Samuel L.
    551     * Jackson.
    552     *
    553     * @access public
    554     * @param  string $actor The actor you are searching for.
    555     * @param  string $mode The section of the site you wish to search in.
    556     *                      Defaults to DVDs.
    557     * @param  interger $page Which page of products to retrieve. Defaults to
    558     *                        the first.
    559     * @return array The array of products retrieved by the query.
    560     * @see    getModes()
    561     */
    562     function searchActor($actor, $mode = 'dvd', $page = 1) {
    563         return $this->_sendRequest(array('ActorSearch' => $actor, 'mode' => $mode), $page);
     534     * Retrieves information about a browse node
     535     *
     536     * Example:
     537     * <code>
     538     * <?php
     539     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     540     * $result = $amazon->BrowseNodeLookup('283155'); // 283155='Books'
     541     * ?>
     542     * </code>
     543     *
     544     * @access public
     545     * @param  string $browsenode_id The browse node ID
     546     * @param  array $options The optional parameters
     547     * @return array The array of information returned by the query
     548     */
     549    function BrowseNodeLookup($browsenode_id, $options = array())
     550    {
     551        $params = $options;
     552        $params['Operation'] = 'BrowseNodeLookup';
     553        $params['BrowseNodeId'] = $browsenode_id;
     554        return $this->_sendRequest($params);
    564555    }
    565556
    566557    /**
    567     * Searches Amazon for movies by their given director.
    568     *
    569     * Example:
    570     * <code>
    571     * <?php
    572     * require_once 'PEAR.php';
    573     * require_once 'Services/Amazon.php';
    574     *
    575     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    576     * $products = $amazon->searchDirector('George Lucas');
    577     *
    578     * if(!PEAR::isError($products)) {
    579     *    var_dump($products);
    580     * } else {
    581     *    echo $products->message;
    582     * }
    583     * ?>
    584     * </code>
    585     * If you were to fill in the Developer token in the constructor this would
    586     * search Amazon.com for DVD movies directed by American film Director
    587     * George Lucas.
    588     *
    589     * @access public
    590     * @param  string $director The director you are searching for.
    591     * @param  string $mode The section of the site you wish to search in
    592     * @param  interger $page Which page of products to retrieve. Defaults to
    593     *                        the first.
    594     * @return array The array of products retrieved by the query.
    595     * @see    getModes()
    596     */
    597     function searchDirector($director, $mode = 'dvd', $page = 1) {
    598         return $this->_sendRequest(array('DirectorSearch' => $director, 'mode' => $mode), $page);
     558     * Adds items to an existing remote shopping cart
     559     *
     560     * Example:
     561     * <code>
     562     * <?php
     563     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     564     * $item = array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1);
     565     * // $item = array(array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1),
     566     * //               array('OfferListingId' => 'bbbbbbbbbb', 'Quantity' => 10),
     567     * //               array('ASIN' => 'cccccccccc', 'Quantity' => 20));
     568     * $result = $amazon->CartAdd('[Cart ID]', '[HMAC]', $item);
     569     * ?>
     570     * </code>
     571     *
     572     * @access public
     573     * @param  string $cart_id A unique identifier for a cart
     574     * @param  string $hmac A unique security token
     575     * @param  array $item Products and the quantities
     576     * @param  array $options The optional parameters
     577     * @return array The array of information returned by the query
     578     * @see    CartClear(), CartCreate(), CartModify()
     579     */
     580    function CartAdd($cart_id, $hmac, $item, $options = array())
     581    {
     582        $params = $options;
     583        $params['Operation'] = 'CartAdd';
     584        $params['CartId'] = $cart_id;
     585        $params['HMAC'] = $hmac;
     586        $params += $this->_assembleItemParameter($item);
     587        return $this->_sendRequest($params);
    599588    }
    600589
    601590    /**
    602     * Search Amazon for products from a specific manufacturer.
    603     *
    604     * This search is synonymous with searching for a book publisher.
    605     *
    606     * Example:
    607     * <code>
    608     * <?php
    609     * require_once 'PEAR.php';
    610     * require_once 'Services/Amazon.php';
    611     *
    612     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    613     * $products = $amazon->searchManufacturer('New Line', 'dvd');
    614     *
    615     * if(!PEAR::isError($products)) {
    616     *    var_dump($products);
    617     * } else {
    618     *    echo $products->message;
    619     * }
    620     * ?>
    621     * </code>
    622     * If you were to fill in the Developer token in the constructor this would
    623     * search Amazon.com for DVD movies put out by American film company New
    624     * Line Cinemas.
    625     *
    626     * @access public
    627     * @param  string $manufacturer The manufacturer you are searching for.
    628     * @param  string $mode The section of the site you wish to search in.
    629     * @param  interger $page Which page of products to retrieve. Defaults to
    630     *                        the first.
    631     * @return array The array of products retrieved by the query.
    632     * @see    getModes()
    633     */
    634     function searchManufacturer($manufacturer, $mode = 'books', $page = 1) {
    635         return $this->_sendRequest(array('ManufacturerSearch' => $manufacturer, 'mode' => $mode), $page);
     591     * Removes all the contents of a remote shopping cart
     592     *
     593     * @access public
     594     * @param  string $cart_id A unique identifier for a cart
     595     * @param  string $hmac A unique security token
     596     * @param  array $options The optional parameters
     597     * @return array The array of information returned by the query
     598     * @see    CartAdd(), CartCreate(), CartGet(), CartModify()
     599     */
     600    function CartClear($cart_id, $hmac, $options = array())
     601    {
     602        $params = $options;
     603        $params['Operation'] = 'CartClear';
     604        $params['CartId'] = $cart_id;
     605        $params['HMAC'] = $hmac;
     606        return $this->_sendRequest($params);
    636607    }
    637    
     608
    638609    /**
    639     * Search Amazon for products from a specific book publisher.
    640     *
    641     * Example:
    642     * <code>
    643     * <?php
    644     * require_once 'PEAR.php';
    645     * require_once 'Services/Amazon.php';
    646     *
    647     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    648     * $products = $amazon->searchPublisher('Coriolis', 'books');
    649     *
    650     * if(!PEAR::isError($products)) {
    651     *    var_dump($products);
    652     * } else {
    653     *    echo $products->message;
    654     * }
    655     * ?>
    656     * </code>
    657     * If you were to fill in the Developer token in the constructor this would
    658     * search Amazon.com for books published by Coriolis Group Books which
    659     * publish the "Black Book" series of programming books, some of my
    660     * favorites.
    661     *
    662     * @access public
    663     * @param  string $manufacturer The manufacturer or book publisher you are
    664     *                              searching for.
    665     * @param  string $mode The section of the site you wish to search in.
    666     * @param  interger $page Which page of products to retrieve. Defaults to
    667     *                        the first.
    668     * @return array The array of products retrieved by the query.
    669     */
    670     function searchPublisher($publisher, $page = 1) {
    671         return $this->searchManufacturer($publisher, 'books', $page);
     610     * Creates a new remote shopping cart
     611     *
     612     * Example:
     613     * <code>
     614     * <?php
     615     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     616     * $item = array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1);
     617     * // $item = array(array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1),
     618     * //               array('ASIN' => 'cccccccccc', 'Quantity' => 20));
     619     * $result = $amazon->CartCreate($item);
     620     * ?>
     621     * </code>
     622     *
     623     * @access public
     624     * @param  array $item Products and the quantities
     625     * @param  array $options The optional parameters
     626     * @return array The array of information returned by the query
     627     * @see    CartAdd(), CartClear(), CartGet(), CartModify()
     628     */
     629    function CartCreate($item, $options = array())
     630    {
     631        $params = $options;
     632        $params['Operation'] = 'CartCreate';
     633        $params += $this->_assembleItemParameter($item);
     634        return $this->_sendRequest($params);
    672635    }
    673636
    674637    /**
    675     * Retrieves a persons wishlist items given their unique ID.
    676     *
    677     * To find a specific wish list ID number, simply travel to the page that
    678     * contains the list that you are interested in, and look for the list's 13
    679     * character ID in web page's URL. (It appears after the "/obidos/registry/"
    680     * string). As an example, the following URL contains the list ID
    681     * 1QKCTUTWKI1AZ: {@link http://www.amazon.com/exec/obidos/registry/1QKCTUTWKI1AZ}.
    682     *
    683     * Example:
    684     * <code>
    685     * <?php
    686     * require_once 'PEAR.php';
    687     * require_once 'Services/Amazon.php';
    688     *
    689     * $amazon = &new Services_Amazon('XXXXXXXXXXXXXX', 'myassociateid');
    690     * $products = $amazon->searchWishlist('1QKCTUTWKI1AZ');
    691     *
    692     * if(!PEAR::isError($products)) {
    693     *    var_dump($products);
    694     * } else {
    695     *    echo $products->message;
    696     * }
    697     * ?>
    698     * </code>
    699     * If you were to fill in the Developer token in the constructor this would
    700     * search Amazon.com for my wishlist and return all the products currently
    701     * on it.
    702     *
    703     * @access public
    704     * @param  string $wishlist The ID of the wishlist you wish to retrieve.
    705     * @return array The array of products retrieved by the query.
    706     */
    707     function searchWishlist($wishlist) {
    708         return $this->_sendRequest(array('WishlistSearch' => $wishlist), 1);
     638     * Retrieves the contents of a remote shopping cart
     639     *
     640     * @access public
     641     * @param  string $cart_id A unique identifier for a cart
     642     * @param  string $hmac A unique security token
     643     * @param  array $options The optional parameters
     644     * @return array The array of information returned by the query
     645     * @see    CartAdd(), CartClear(), CartCreate(), CartModify()
     646     */
     647    function CartGet($cart_id, $hmac, $options = array())
     648    {
     649        $params = $options;
     650        $params['Operation'] = 'CartGet';
     651        $params['CartId'] = $cart_id;
     652        $params['HMAC'] = $hmac;
     653        return $this->_sendRequest($params);
    709654    }
    710655
    711656    /**
    712     * Reformats the results returned from Amazon into something more standardized.
    713     *
    714     * @access private
    715     * @param  array $products The array of products returned from Amazon's web services
    716     * @return array An array of items that include all basic information about an item.
    717     */
    718     function &_processPage($products) {
    719         $items = array();
     657     * Modifies the quantity of items in a cart and changes cart items to saved items
     658     *
     659     * Example:
     660     * <code>
     661     * <?php
     662     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     663     * $item = array('CartItemId' => 'aaaaaaaaaa', 'Quantity' => 1);
     664     * // $item = array('CartItemId' => 'aaaaaaaaaa', 'Action' => 'SaveForLater');
     665     * // $item = array(array('CartItemId' => 'aaaaaaaaaa', 'Quantity' => 1),
     666     * //               array('CartItemId' => 'cccccccccc', 'Quantity' => 20));
     667     * $result = $amazon->CartModify('[Cart ID]', '[HMAC]', $item);
     668     * ?>
     669     * </code>
     670     *
     671     * @access public
     672     * @param  string $cart_id A unique identifier for a cart
     673     * @param  string $hmac A unique security token
     674     * @param  array $item The CartItemId and the quantities or the Action
     675     * @param  array $options The optional parameters
     676     * @return array The array of information returned by the query
     677     * @see    CartAdd(), CartClear(), CartCreate(), CartGet()
     678     */
     679    function CartModify($cart_id, $hmac, $item, $options = array())
     680    {
     681        $params = $options;
     682        $params['Operation'] = 'CartModify';
     683        $params['CartId'] = $cart_id;
     684        $params['HMAC'] = $hmac;
     685        $params += $this->_assembleItemParameter($item);
     686        return $this->_sendRequest($params);
     687    }
    720688
    721         foreach($products as $url => $product) {
    722             $item         = array();
    723             $item['url']  = $url;
    724             $item['asin'] = $product->Asin;
    725             $item['name'] = $product->ProductName;
    726             $item['type'] = $product->Catalog;
    727             if (isset($product->Authors)) {
    728                 if (is_array($product->Authors->Author)) {
    729                     foreach ($product->Authors->Author as $author) {
    730                         $item['authors'][] = $author;
    731                     }
    732                 } else {
    733                     $item['authors'][] = $product->Authors->Author;
    734                 }
     689    /**
     690     * Retrieves publicly available content written by specific Amazon customers
     691     *
     692     * @access public
     693     * @param  string $customer_id A customer ID
     694     * @param  array $options The optional parameters
     695     * @return array The array of information returned by the query
     696     * @see    CustomerContentSearch()
     697     */
     698    function CustomerContentLookup($customer_id, $options = array())
     699    {
     700        $params = $options;
     701        $params['Operation'] = 'CustomerContentLookup';
     702        $params['CustomerId'] = $customer_id;
     703        return $this->_sendRequest($params);
     704    }
     705
     706    /**
     707     * Searches for Amazon customers by name or email address
     708     *
     709     * @access public
     710     * @param  array $customer A customer's name or its email
     711     * @param  array $options The optional parameters
     712     * @return array The array of information returned by the query
     713     * @see    CustomerContentLookup()
     714     */
     715    function CustomerContentSearch($customer = null, $options = array())
     716    {
     717        $params = $options;
     718        $params['Operation'] = 'CustomerContentSearch';
     719        $params += $customer;
     720        return $this->_sendRequest($params);
     721    }
     722
     723    /**
     724     * Retrieves information about operations and response groups
     725     *
     726     * Example:
     727     * <code>
     728     * <?php
     729     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     730     * $result = $amazon->Help('Operation', 'ItemLookup');
     731     * ?>
     732     * </code>
     733     *
     734     * @access public
     735     * @param  string $help_type The type of information
     736     * @param  string $about The name of an operation or a response group
     737     * @param  array $options The optional parameters
     738     * @return array The array of information returned by the query
     739     */
     740    function Help($help_type, $about, $options = array())
     741    {
     742        $params = $options;
     743        $params['Operation'] = 'Help';
     744        $params['HelpType'] = $help_type;
     745        $params['About'] = $about;
     746        return $this->_sendRequest($params);
     747    }
     748       
     749    /**
     750     * Retrieves information for products
     751     *
     752     * Example:
     753     * <code>
     754     * <?php
     755     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     756     * $options = array();
     757     * $options['ResponseGroup'] = 'Large';
     758     * $result = $amazon->ItemLookup('[ASIN(s)]', $options);
     759     * ?>
     760     * </code>
     761     *
     762     * @access public
     763     * @param  string $item_id Product IDs
     764     * @param  array $options The optional parameters
     765     * @return array The array of information returned by the query
     766     * @see    ItemSearch()
     767     */
     768    function ItemLookup($item_id, $options = array())
     769    {
     770        $params = $options;
     771        $params['Operation'] = 'ItemLookup';
     772        if (is_array($item_id)) {
     773            $item_id = implode(',', $item_id);
     774        }
     775        $params['ItemId'] = $item_id;
     776        return $this->_sendRequest($params);
     777    }
     778
     779    /**
     780     * Searches for products
     781     *
     782     * Example:
     783     * <code>
     784     * <?php
     785     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     786     * $options = array();
     787     * $options['Keywords'] = 'sushi';
     788     * $options['Sort'] = 'salesrank';
     789     * $options['ResponseGroup'] = 'ItemIds,ItemAttributes,Images';
     790     * $result = $amazon->ItemSearch('Books', $options);
     791     * ?>
     792     * </code>
     793     *
     794     * @access public
     795     * @param  string $search_index A search index
     796     * @param  array $options The optional parameters
     797     * @return array The array of information returned by the query
     798     * @see    ItemLookup()
     799     */
     800    function ItemSearch($search_index, $options = array())
     801    {
     802        $params = $options;
     803        $params['Operation'] = 'ItemSearch';
     804        $params['SearchIndex'] = $search_index;
     805        return $this->_sendRequest($params);
     806    }
     807
     808    /**
     809     * Retrieves products in a specific list
     810     *
     811     * @access public
     812     * @param  string $list_type The type of list
     813     * @param  string $list_id A list ID
     814     * @param  array $options The optional parameters
     815     * @return array The array of information returned by the query
     816     * @see    ListSearch()
     817     */
     818    function ListLookup($list_type, $list_id, $options = array())
     819    {
     820        $params = $options;
     821        $params['Operation'] = 'ListLookup';
     822        $params['ListType'] = $list_type;
     823        $params['ListId'] = $list_id;
     824        return $this->_sendRequest($params);
     825    }
     826
     827    /**
     828     * Searches for a wish list, baby registry, or wedding registry
     829     *
     830     * Example:
     831     * <code>
     832     * <?php
     833     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     834     * $keywords = array('Name' => 'hoge');
     835     * $result = $amazon->ListSearch('WishList', $keywords);
     836     * ?>
     837     * </code>
     838     *
     839     * @access public
     840     * @param  string $list_type The type of list
     841     * @param  array $keywords Parameters to search for
     842     * @param  array $options The optional parameters
     843     * @return array The array of information returned by the query
     844     * @see    ListLookup()
     845     */
     846    function ListSearch($list_type, $keywords, $options = array())
     847    {
     848        $params = $options;
     849        $params['Operation'] = 'ListSearch';
     850        $params['ListType'] = $list_type;
     851        $params += $keywords;
     852        return $this->_sendRequest($params);
     853    }
     854
     855    /**
     856     * Retrieves information about Amazon zShops and Marketplace products
     857     *
     858     * @access public
     859     * @param  string $id_type The type of ID
     860     * @param  string $id The exchange ID or the listing ID
     861     * @param  array $options The optional parameters
     862     * @return array The array of information returned by the query
     863     * @see    SellerListingSearch()
     864     */
     865    function SellerListingLookup($id_type, $id, $options = array())
     866    {
     867        $params = $options;
     868        $params['Operation'] = 'SellerListingLookup';
     869        $params['IdType'] = $id_type;
     870        $params['Id'] = $id;
     871        return $this->_sendRequest($params);
     872    }
     873
     874    /**
     875     * Searches for Amazon zShops and Marketplace products
     876     *
     877     * Example:
     878     * <code>
     879     * <?php
     880     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     881     * $keywords = array('Keywords' => 'pizza');
     882     * $result = $amazon->SellerListingSearch('zShops', $keywords);
     883     * ?>
     884     * </code>
     885     *
     886     * @access public
     887     * @param  string $search_index The type of seller listings
     888     * @param  array $options The optional parameters
     889     * @return array The array of information returned by the query
     890     * @see    SellerListingLookup()
     891     */
     892    function SellerListingSearch($search_index, $options = array())
     893    {
     894        $params = $options;
     895        $params['Operation'] = 'SellerListingSearch';
     896        $params['SearchIndex'] = $search_index;
     897        return $this->_sendRequest($params);
     898    }
     899
     900    /**
     901     * Retrieves information about specific sellers
     902     *
     903     * @access public
     904     * @param  string $seller_id IDs for Amazon sellers
     905     * @param  array $options The optional parameters
     906     * @return array The array of information returned by the query
     907     */
     908    function SellerLookup($seller_id, $options = array())
     909    {
     910        $params = $options;
     911        $params['Operation'] = 'SellerLookup';
     912        $params['SellerId'] = $seller_id;
     913        return $this->_sendRequest($params);
     914    }
     915
     916    /**
     917     * Retrieves products that are similar to Amazon products
     918     *
     919     * @access public
     920     * @param  string $item_id Product IDs
     921     * @param  array $options The optional parameters
     922     * @return array The array of information returned by the query
     923     */
     924    function SimilarityLookup($item_id, $options = array())
     925    {
     926        $params = $options;
     927        $params['Operation'] = 'SimilarityLookup';
     928        if (is_array($item_id)) {
     929            $item_id = implode(',', $item_id);
     930        }
     931        $params['ItemId'] = $item_id;
     932        return $this->_sendRequest($params);
     933    }
     934
     935    /**
     936     * Retrieves information about tags
     937     *
     938     * @access public
     939     * @param  string $tag_name List of tag names
     940     * @param  array $options The optional parameters
     941     * @return array The array of information returned by the query
     942     */
     943    function TagLookup($tag_name, $options = array())
     944    {
     945        $params = $options;
     946        $params['Operation'] = 'TagLookup';
     947        if (is_array($tag_name)) {
     948            $tag_name = implode(',', $tag_name);
     949        }
     950        $params['TagName'] = $tag_name;
     951        return $this->_sendRequest($params);
     952    }
     953
     954    /**
     955     * Retrieves information about the status of financial transactions
     956     *
     957     * @access public
     958     * @param  string $transaction_id Transaction IDs
     959     * @param  array $options The optional parameters
     960     * @return array The array of information returned by the query
     961     */
     962    function TransactionLookup($transaction_id, $options = array())
     963    {
     964        $params = $options;
     965        $params['Operation'] = 'TransactionLookup';
     966        $params['TransactionId'] = $transaction_id;
     967        return $this->_sendRequest($params);
     968    }
     969
     970    /**
     971     * Retrieves information about a car part
     972     *
     973     * @access public
     974     * @param  array $options The optional parameters
     975     * @return array The array of information returned by the query
     976     */
     977    function VehiclePartLookup($options = array())
     978    {
     979        $params = $options;
     980        $params['Operation'] = 'VehiclePartLookup';
     981        return $this->_sendRequest($params);
     982    }
     983
     984    /**
     985     * Searches the parts that work in the car
     986     *
     987     * @access public
     988     * @param  string $make_id
     989     * @param  string $model_id
     990     * @param  string $year
     991     * @param  array $options The optional parameters
     992     * @return array The array of information returned by the query
     993     */
     994    function VehiclePartSearch($make_id, $model_id, $year, $options = array())
     995    {
     996        $params = $options;
     997        $params['Operation'] = 'VehiclePartSearch';
     998        $params['MakeId'] = $make_id;
     999        $params['ModelId'] = $model_id;
     1000        $params['Year'] = $year;
     1001        return $this->_sendRequest($params);
     1002    }
     1003
     1004    /**
     1005     * Searches all vehicles
     1006     *
     1007     * @access public
     1008     * @param  array $options The optional parameters
     1009     * @return array The array of information returned by the query
     1010     */
     1011    function VehicleSearch($options = array())
     1012    {
     1013        $params = $options;
     1014        $params['Operation'] = 'VehicleSearch';
     1015        return $this->_sendRequest($params);
     1016    }
     1017
     1018    /**
     1019     * Combines requests for the same operation into a single request
     1020     *
     1021     * Example:
     1022     * <code>
     1023     * <?php
     1024     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     1025     * $shared = array('SearchIndex' => 'Books',
     1026     *                 'Keywords' => 'php');
     1027     * $params1 = array('ItemPage' => '1');
     1028     * $params2 = array('ItemPage' => '2');
     1029     * $result = $amazon->doBatch('ItemSearch', $shared, $params1, $params2);
     1030     * ?>
     1031     * </code>
     1032     *
     1033     * @access public
     1034     * @param  string $operation The operation
     1035     * @param  array $shared Shared parameters
     1036     * @param  array $params1 The parameters specific to the first request
     1037     * @param  array $params2 The parameters specific to the second request
     1038     * @return array The array of information returned by the query
     1039     */
     1040    function doBatch($operation, $shared, $params1 = array(), $params2 = array())
     1041    {
     1042        $params = array();
     1043        $params['Operation'] = $operation;
     1044        foreach ($shared as $k => $v) {
     1045            $params[$operation . '.Shared.' . $k] = $v;
     1046        }
     1047        foreach ($params1 as $k => $v) {
     1048            $params[$operation . '.1.' . $k] = $v;
     1049        }
     1050        foreach ($params2 as $k => $v) {
     1051            $params[$operation . '.2.' . $k] = $v;
     1052        }
     1053        return $this->_sendRequest($params);
     1054    }
     1055
     1056    /**
     1057     * Combines the different operations into a single request
     1058     *
     1059     * Example:
     1060     * <code>
     1061     * <?php
     1062     * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
     1063     * $params1 = array('SearchIndex' => 'Books',
     1064     *                  'Title' => 'sushi');
     1065     * $params2 = array('Keywords' => 'tempura');
     1066     * $result = $amazon->doMultiOperation('ItemSearch', $params1,
     1067     *                                     'SellerListingSearch', $params2);
     1068     * ?>
     1069     * </code>
     1070     *
     1071     * @access public
     1072     * @param  string $operation1 The first operation
     1073     * @param  array $params1 The parameters specific to the first request
     1074     * @param  string $operation2 The second operation
     1075     * @param  array $params2 The parameters specific to the second request
     1076     * @return array The array of information returned by the query
     1077     */
     1078    function doMultiOperation($operation1, $params1, $operation2, $params2)
     1079    {
     1080        $params = array();
     1081        $params['Operation'] = $operation1 . ',' . $operation2;
     1082        foreach ($params1 as $k => $v) {
     1083            $params[$operation1 . '.1.' . $k] = $v;
     1084        }
     1085        foreach ($params2 as $k => $v) {
     1086            $params[$operation2 . '.1.' . $k] = $v;
     1087        }
     1088        return $this->_sendRequest($params);
     1089    }
     1090
     1091    /**
     1092     * Assembles the Item parameters
     1093     *
     1094     * @access private
     1095     * @param  array $items The items
     1096     * @return array The item parameters
     1097     */
     1098    function _assembleItemParameter($items)
     1099    {
     1100        $params = array();
     1101        if (!is_array(current($items))) {
     1102            $items = array(0 => $items);
     1103        }
     1104        $i = 1;
     1105        foreach ($items as $item) {
     1106            foreach ($item as $k => $v) {
     1107                $params['Item.' . $i . '.' . $k] = $v;
    7351108            }
    736             if (isset($product->Artists)) {
    737                 if (is_array($product->Artists->Artist)) {
    738                     foreach ($product->Artists->Artist as $artist) {
    739                         $item['artists'][] = $artist;
    740                     }
    741                 } else {
    742                     $item['artists'][] = $product->Artists->Artist;
    743                 }
     1109            $i++;
     1110        }
     1111        return $params;
     1112    }
     1113
     1114    /**
     1115     * Ignores the caching of specific operations
     1116     *
     1117     * @access private
     1118     * @param  string $operation The operation
     1119     * @return bool Returns true if the operation isn't cached, false otherwise
     1120     */
     1121    function _ignoreCache($operation)
     1122    {
     1123        $ignore = array('CartAdd', 'CartClear', 'CartGet', 'CartModify', 'TransactionLookup');
     1124        if (!strchr($operation, ',')) {
     1125            return in_array($operation, $ignore);
     1126        }
     1127        $operations = explode(',', $operation);
     1128        foreach ($operations as $v) {
     1129            if (in_array($v, $ignore)) {
     1130                return true;
    7441131            }
    745             $item['release']      = isset($product->ReleaseDate) ? $product->ReleaseDate : null;
    746             $item['manufacturer'] = isset($product->Manufacturer) ? $product->Manufacturer : null;
    747             $item['imagesmall']   = $product->ImageUrlSmall;
    748             $item['imagemedium']  = $product->ImageUrlMedium;
    749             $item['imagelarge']   = $product->ImageUrlLarge;
    750             $item['listprice']    = isset($product->ListPrice) ? $product->ListPrice : null;
    751             $item['ourprice']     = isset($product->ListPrice) ? $product->ListPrice : null;
     1132        }
     1133        return false;
     1134    }
    7521135
    753             $items[] = $item;
     1136    /**
     1137     * Generates ID used as cache identifier
     1138     *
     1139     * @access private
     1140     * @param  array $params
     1141     * @return string Cache ID
     1142     */
     1143    function _generateCacheId($params)
     1144    {
     1145        unset($params['AWSAccessKeyId']);
     1146        unset($params['AssociateTag']);
     1147        $str = '';
     1148        foreach ($params as $k => $v) {
     1149            $str .= $k . $v;
    7541150        }
     1151        return md5($str);
     1152    }
    7551153
    756         return $items;
     1154    /**
     1155     * Encode URL according to RFC 3986
     1156     *
     1157     * @access private
     1158     * @param string $str UTF-8 string
     1159     * @return string Encoded string
     1160     */
     1161    function _urlencode($str)
     1162    {
     1163        return str_replace('%7E', '~', rawurlencode($str));
    7571164    }
    7581165
    7591166    /**
    760     * Sends the request to Amazons Web Services.
    761     *
    762     * @access private
    763     * @param  array   $params An array of url parameters to pass. With the key being the variable for the value.
    764     * @param  integer $page   Which page of products to retrieve. Defaults to the first.
    765     * @return mixed Returns a PEAR_Error on error and an array of products on success.
    766     */
    767     function &_sendRequest($params = array(), $page = 1) {
    768         if (is_null($this->_token) || is_null($this->_affid)) {
    769             return PEAR::raiseError('Developers token or Affiliate ID have not been set.');
     1167     * Create an HMAC-SHA256
     1168     *
     1169     * @access private
     1170     * @param string $string_to_sign
     1171     * @param string $secret_access_key
     1172     * @return string hash
     1173     */
     1174    function _hash($string_to_sign, $secret_access_key)
     1175    {
     1176        if (function_exists('hash_hmac')) {
     1177            return hash_hmac('sha256', $string_to_sign, $secret_access_key, true);
     1178        } elseif (function_exists('mhash')) {
     1179            return mhash(MHASH_SHA256, $string_to_sign, $secret_access_key);
    7701180        }
    7711181
    772         // Get base url and append all params after url encoding them
    773         $url = $this->_baseurl . '?locale=' . $this->_locale . '&type=lite&f=xml&t=' . $this->_affid . '&dev-t=' . $this->_token . '&page=' . $page;
    774         foreach ($params as $key => $value) {
    775             if(!is_null($value)) {
    776                 $url .= '&' . $key . '=' . urlencode($value);
    777             }
     1182        return PEAR::raiseError('hash_hmac/mhash is required');
     1183    }
     1184
     1185    /**
     1186     * Builds a URL
     1187     *
     1188     * @access private
     1189     * @param array $params
     1190     * @return string URL
     1191     */
     1192    function _buildUrl($params)
     1193    {
     1194        $params['Service'] = 'AWSECommerceService';
     1195        $params['AWSAccessKeyId'] = $this->_access_key_id;
     1196        if (!empty($this->_associate_tag)) {
     1197            $params['AssociateTag'] = $this->_associate_tag;
    7781198        }
     1199        $params['Version'] = $this->_version;
     1200        $params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z', is_null($this->_timestamp) ? time() : $this->_timestamp);
    7791201
    780         // Open up our HTTP_Request and set our User-Agent field then send the
    781         // request for the URL.
     1202        // sort parameters by byte value
     1203        ksort($params);
     1204
     1205        // create a canonical string
     1206        $canonical_string = '';
     1207        foreach ($params as $k => $v) {
     1208            $canonical_string .= '&' . $this->_urlencode($k) . '=' . $this->_urlencode($v);
     1209        }
     1210        $canonical_string = substr($canonical_string, 1);
     1211
     1212        // create a signature for request
     1213        $parsed_url = parse_url($this->_baseurl);
     1214        $string_to_sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$canonical_string}";
     1215        $signature = $this->_hash($string_to_sign, $this->_secret_access_key);
     1216        if (PEAR::isError($signature)) {
     1217            return $signature;
     1218        }
     1219        $signature = base64_encode($signature);
     1220
     1221        // create a signed url
     1222        $url = $this->_baseurl . '?' . $canonical_string . '&Signature=' . $this->_urlencode($signature);
     1223
     1224        return $url;
     1225    }
     1226
     1227    /**
     1228     * Sends a request
     1229     *
     1230     * @access private
     1231     * @param string $url
     1232     * @return string The response
     1233     */
     1234    function _sendHttpRequest($url)
     1235    {
    7821236        $http = &new HTTP_Request($url);
     1237        $http->setHttpVer('1.0');
    7831238        $http->addHeader('User-Agent', 'Services_Amazon/' . $this->getApiVersion());
    784         $http->sendRequest();
    785        
    786         // Retrieve the result and check that its HTTP 200 Ok. Otherwise raise
    787         // an error.
    788         if ($http->getResponseCode() != 200) {
    789             return PEAR::raiseError('Amazon return HTTP ' . $http->getResponseCode());
     1239        if ($this->_proxy_host) {
     1240            $http->setProxy($this->_proxy_host, $this->_proxy_port, $this->_proxy_user, $this->_proxy_pass);
    7901241        }
    791         $result = $http->getResponseBody();
    792        
    793         // Start up the XML_Unserializer and feed it the data received from
    794         // Amazon.com
    795         $xml = &new XML_Unserializer(array('complexType' => 'object', 'keyAttribute' => 'url'));
    796         $xml->unserialize($result, false);
     1242
     1243        $result = $http->sendRequest();
     1244        if (PEAR::isError($result)) {
     1245            return PEAR::raiseError('HTTP_Request::sendRequest failed: ' . $result->message);
     1246        }
     1247
     1248        if ($http->getResponseCode() != 200){
     1249            return PEAR::raiseError('Amazon returned invalid HTTP response code ' . $http->getResponseCode());
     1250        }
     1251        return $http->getResponseBody();
     1252    }
     1253
     1254    /**
     1255     * Parses raw XML result
     1256     *
     1257     * @access private
     1258     * @param string $raw_result
     1259     * @return string The contents
     1260     */
     1261    function _parseRawResult($raw_result)
     1262    {
     1263        $xml = &new XML_Unserializer();
     1264        $xml->setOption(XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE, true);
     1265        $xml->setOption(XML_UNSERIALIZER_OPTION_FORCE_ENUM,
     1266                        array('Item', 'Review', 'EditorialReview',
     1267                              'Parameter', 'Author', 'Creator', 'ResponseGroup', 'Error'));
     1268        $xml->unserialize($raw_result, false);
    7971269        $data = $xml->getUnserializedData();
    798        
    799         // Check to make sure Amazon didn't give us an error. If so raise it.
    800         if (isset($data->ErrorMsg)) {
    801             return PEAR::raiseError($data->ErrorMsg);
     1270        if (PEAR::isError($data)) {
     1271            return $data;
    8021272        }
    803        
    804         // Prepare the data to be sent to _processPage
    805         $data  = get_object_vars($data);
    806         $pages = isset($data['TotalPages']) ? (int) $data['TotalPages'] : 1;
    807         unset($data['TotalPages']);
    808         $totalresults = isset($data['TotalResults']) ? $data['TotalResults'] : count($data);
    809         unset($data['TotalResults']);
    8101273
    811         $products = $this->_processPage($data);
    812         $products['page']  = $page;
    813         $products['pages'] = $pages;
    814         $products['totalresults'] = $totalresults;
     1274        if (isset($data['Error'])) {
     1275            $this->_errors = $data['Error'];
     1276            return PEAR::raiseError(implode(':', $this->getError()));
     1277        }
    8151278
    816         return $products;
     1279        if (isset($data['OperationRequest']['RequestProcessingTime'])) {
     1280            $this->_processing_time = $data['OperationRequest']['RequestProcessingTime'];
     1281        }
     1282
     1283        if (isset($data['OperationRequest']['Errors'])) {
     1284            $this->_errors = $data['OperationRequest']['Errors']['Error'];
     1285            return PEAR::raiseError(implode(':', $this->getError()));
     1286        }
     1287
     1288        // Get values of the second level content elements
     1289        unset($data['xmlns']);
     1290        unset($data['OperationRequest']);
     1291        $contents = array();
     1292        $keys = array_keys($data);
     1293        foreach ($keys as $v) {
     1294            if (strstr($v, 'Response')) {
     1295                $data[$v] = current($data[$v]);
     1296                $contents[$v] = $data[$v];
     1297            } else {
     1298                $contents = $data[$v];
     1299            }
     1300            $result = $this->_checkContentError($data[$v]);
     1301            if (PEAR::isError($result)) {
     1302                return $result;
     1303            }
     1304        }
     1305        return $contents;
    8171306    }
     1307
     1308    /**
     1309     * Checks error codes at the content elements
     1310     *
     1311     * @access private
     1312     * @param  array $content Values of the content elements
     1313     * @return array mixed A PEAR_Error on error, a true on success
     1314     * @see    _parseRawResult
     1315     */
     1316    function _checkContentError($content)
     1317    {
     1318        if (isset($content['Request']['Errors'])) {
     1319            $this->_errors = $content['Request']['Errors']['Error'];
     1320            return PEAR::raiseError(implode(':', $this->getError()));
     1321        } else if (isset($content[0])) {
     1322            $errors = array();
     1323            foreach ($content as $v) {
     1324                if (isset($v['Request']['Errors']['Error'])) {
     1325                    $errors = array_merge($errors, $v['Request']['Errors']['Error']);
     1326                }
     1327            }
     1328            if (!empty($errors)) {
     1329                $this->_errors = $errors;
     1330                return PEAR::raiseError(implode(':', $this->getError()));
     1331            }
     1332        }
     1333        return true;
     1334    }
     1335
     1336    /**
     1337     * Sends the request to Amazon
     1338     *
     1339     * @access private
     1340     * @param  array $params The array of request parameters
     1341     * @return array The array of information returned by the query
     1342     */
     1343    function _sendRequest($params)
     1344    {
     1345        $this->_errors = array();
     1346
     1347        if (is_null($this->_access_key_id)) {
     1348            return PEAR::raiseError('Access Key ID have not been set');
     1349        }
     1350
     1351        $url = $this->_buildUrl($params);
     1352        $this->_lasturl = $url;
     1353        if (PEAR::isError($url)) {
     1354            return $url;
     1355        }
     1356
     1357        // Return cached data if available
     1358        $cache_id = false;
     1359        if (isset($this->_cache) && !$this->_ignoreCache($params['Operation'])) {
     1360            $cache_id = $this->_generateCacheId($params);
     1361            $cache = $this->_cache->get($cache_id);
     1362            if (!is_null($cache)) {
     1363                $this->_processing_time = 0;
     1364                return $cache;
     1365            }
     1366        }
     1367
     1368        $result = $this->_sendHttpRequest($url);
     1369        $this->_raw_result = $result;
     1370        if (PEAR::isError($result)) {
     1371            return $result;
     1372        }
     1373
     1374        $contents = $this->_parseRawResult($result);
     1375        if (PEAR::isError($contents)) {
     1376            return $contents;
     1377        }
     1378
     1379        if ($cache_id) {
     1380            $this->_cache->save($cache_id, $contents, $this->_cache_expire);
     1381        }
     1382
     1383        return $contents;
     1384    }
     1385
    8181386}
    8191387?>
  • config.php.sample

     
    468468///
    469469define('GOOGLE_AJAX_SEARCH_API_KEY', '');
    470470
     471///
     472// Amazon Product Advertising API
     473// 2009年8月15日以降、Amazon の仕様変更の影響により
     474// AMAZON_ACCESS_KEY_ID と AMAZON_SECRET_ACCESS_KEY を設定しないと、
     475// レビュー機能がご利用いただけなくなりますのでご注意ください。
     476// https://affiliate-program.amazon.com/gp/flex/advertising/api/sign-in-jp.html  から取得
     477///
     478define('AMAZON_ACCESS_KEY_ID', '');
     479
     480// Amazon Secret Access Key
     481define('AMAZON_SECRET_ACCESS_KEY', '');
     482
    471483//// SNSアプリケーション設定 ////
    472484
    473485// 管理画面のURL設定
  • webapp/lib/OpenPNE/Config.php

     
    225225            'OPENPNE_ADMIN_CONVERT_URL' => true,
    226226            'CHECK_IMG_AUTH' => false,
    227227            'OPENPNE_IS_OPENID_SERVER' => false,
     228            'AMAZON_ACCESS_KEY_ID' => '',
     229            'AMAZON_SECRET_ACCESS_KEY' => '',
    228230        // 固定値
    229             'AMAZON_TOKEN'   => '1WZYY1W9YF49AGM0RTG2',
    230231            'AMAZON_LOCALE'  => 'jp',
    231             'AMAZON_BASEURL' => 'http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService',
     232            'AMAZON_BASEURL' => 'http://ecs.amazonaws.jp/onca/xml',
    232233            'OPENPNE_REGIST_FROM_NONE'   => 0,
    233234            'OPENPNE_REGIST_FROM_PC'     => 1,
    234235            'OPENPNE_REGIST_FROM_KTAI'   => 2,
  • webapp/lib/OpenPNE/Amazon.php

     
    44 * @license   http://www.php.net/license/3_01.txt PHP License 3.01
    55 */
    66
    7 require_once 'Services/AmazonECS4.php';
     7require_once 'Services/Amazon.php';
    88
    99/**
    1010 * OpenPNEでAmazonECSを利用するためのクラス
     
    1212 * @package OpenPNE
    1313 * @author Kousuke Ebihara <ebihara@tejimaya.com>
    1414 */
    15 class OpenPNE_Amazon extends Services_AmazonECS4
     15class OpenPNE_Amazon extends Services_Amazon
    1616{
    1717    /**
    1818     * Category(AmazonECS3)とSearchIndexの変換テーブル
  • webapp/lib/db/review.php

     
    9696    }
    9797
    9898    require_once 'OpenPNE/Amazon.php';
    99     $amazon =& new OpenPNE_Amazon(AMAZON_TOKEN, AMAZON_AFFID);
     99    $amazon =& new OpenPNE_Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_ACCESS_KEY, AMAZON_AFFID);
    100100    $amazon->setLocale(AMAZON_LOCALE);
    101101    $amazon->setBaseUrl(AMAZON_BASEURL);
    102102    if (OPENPNE_USE_HTTP_PROXY) {
     
    138138function db_review_write_product4asin($asin)
    139139{
    140140    require_once 'OpenPNE/Amazon.php';
    141     $amazon =& new OpenPNE_Amazon(AMAZON_TOKEN, AMAZON_AFFID);
     141    $amazon =& new OpenPNE_Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_ACCESS_KEY, AMAZON_AFFID);
    142142    $amazon->setLocale(AMAZON_LOCALE);
    143143    $amazon->setBaseUrl(AMAZON_BASEURL);
    144144    if (OPENPNE_USE_HTTP_PROXY) {
  • webapp/lib/util/util.php

     
    1818            $params['ksid'] = session_id();
    1919        }
    2020    }
    21     if ($module == 'admin') {
    22         $module = ADMIN_MODULE_NAME;
    23     }
    2421    $url = openpne_gen_url($module, $action, $params);
    2522    client_redirect_absolute($url);
    2623}
     
    8582    } else {
    8683        unset($p['ssl_param']);
    8784    }
     85    if ($p['m'] == 'admin') {
     86        $p['m'] = ADMIN_MODULE_NAME;
     87    }
    8888    if ($q = http_build_query($p)) {
    8989        $url .= '?' . $q;
    9090    }
  • webapp/modules/setup/templates/setup_done.tpl

     
    88<li><a href="({t_url m=$smarty.const.ADMIN_MODULE_NAME})">管理画面へ</a></li>
    99</ul>
    1010
    11 <ul>
    12 <li><a href="http://owners.pne.jp/?m=pc&amp;a=page_o_public_invite" target="_blank">PNEオーナーズSNSに登録</a></li>
    13 </ul>
    14 
    1511({ext_include file="inc_footer.tpl"})
  • webapp/modules/pc/templates/h_message.tpl

     
    6565
    6666({if $c_message.filename && $smarty.const.OPENPNE_USE_FILEUPLOAD})
    6767<div class="block attachFile"><ul>
    68 <li><a href="({t_url m=pc a=do_h_message_file_download})&amp;target_c_message_id=({$c_message.c_message_id})&amp;sessid=({$PHPSESSID})">({$c_message.original_filename})</a></li>
     68<li><a href="({t_url m=pc a=do_h_message_file_download})&amp;target_c_message_id=({$c_message.c_message_id})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">({$c_message.original_filename})</a></li>
    6969</ul></div>
    7070({/if})
    7171
  • webapp/modules/pc/templates/c_topic_detail.tpl

     
    3131</div>
    3232({if $c_topic.filename && $smarty.const.OPENPNE_USE_FILEUPLOAD})
    3333<div class="block attachFile"><ul>
    34 <li><a href="({t_url m=pc a=do_c_file_download})&amp;target_c_commu_topic_id=({$c_topic.c_commu_topic_id})&amp;sessid=({$PHPSESSID})">({$c_topic.original_filename})</a></li>
     34<li><a href="({t_url m=pc a=do_c_file_download})&amp;target_c_commu_topic_id=({$c_topic.c_commu_topic_id})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">({$c_topic.original_filename})</a></li>
    3535</ul></div>
    3636({/if})
    3737</dd>
     
    108108</div>
    109109({if $item.filename && $smarty.const.OPENPNE_USE_FILEUPLOAD})
    110110<div class="block attachFile"><ul>
    111 <li><a href="({t_url m=pc a=do_c_file_download})&amp;target_c_commu_topic_comment_id=({$item.c_commu_topic_comment_id})&amp;sessid=({$PHPSESSID})">({$item.original_filename})</a></li>
     111<li><a href="({t_url m=pc a=do_c_file_download})&amp;target_c_commu_topic_comment_id=({$item.c_commu_topic_comment_id})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">({$item.original_filename})</a></li>
    112112</ul></div>
    113113({/if})
    114114</dd>
  • webapp/modules/pc/templates/c_topic_write_delete_confirm.tpl

     
    1616</td></tr>
    1717({if $smarty.const.OPENPNE_USE_FILEUPLOAD})
    1818({if $c_commu_topic_comment.filename})
    19 <tr><th>ファイル</th><td><a href="({t_url m=pc a=do_c_file_download})&amp;target_c_commu_topic_comment_id=({$c_commu_topic_comment.c_commu_topic_comment_id})&amp;sessid=({$PHPSESSID})">({$c_commu_topic_comment.original_filename})</a></td></tr>
     19<tr><th>ファイル</th><td><a href="({t_url m=pc a=do_c_file_download})&amp;target_c_commu_topic_comment_id=({$c_commu_topic_comment.c_commu_topic_comment_id})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">({$c_commu_topic_comment.original_filename})</a></td></tr>
    2020({/if})
    2121({/if})
    2222</table>
  • webapp/modules/pc/templates/h_review_search.tpl

     
    11<div id="LayoutC">
    22<div id="Center">
    33
     4({capture name="keyword_url"})({$keyword|escape:url|smarty:nodefaults})({/capture})
     5
    46({* {{{ searchFormBox *})
    57<div class="dparts searchFormBox"><div class="parts">
    68<div class="partsHeading"><h3>レビュー検索・並び替え</h3></div>
     
    911({t_form_block m=pc a=page_h_review_search})
    1012<p class="form">
    1113<span class="label">並び替え</span>
    12 <a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$keyword|escape:url|smarty:nodefaults})&amp;category=({$category})&amp;orderby=r_num">登録数順</a>
     14<a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$smarty.capture.keyword_url|smarty:nodefaults})&amp;category=({$category})&amp;orderby=r_num">登録数順</a>
    1315|
    14 <a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$keyword|escape:url|smarty:nodefaults})&amp;category=({$category})&amp;orderby=r_datetime">作成日順</a>
     16<a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$smarty.capture.keyword_url|smarty:nodefaults})&amp;category=({$category})&amp;orderby=r_datetime">作成日順</a>
    1517</p>
    1618
    1719<p class="form">
     
    5355
    5456({capture name=pager})({strip})
    5557<div class="pagerRelative">
    56 ({if $is_prev})<p class="prev"><a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$keyword})&amp;category=({$category})&amp;orderby=({$orderby})&amp;page=({$page-1})">前を表示</a></p>({/if})
     58({if $is_prev})<p class="prev"><a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$smarty.capture.keyword_url|smarty:nodefaults})&amp;category=({$category})&amp;orderby=({$orderby})&amp;page=({$page-1})">前を表示</a></p>({/if})
    5759<p class="number">({$start_num})件~({$end_num})件を表示</p>
    58 ({if $is_next})<p class="next"><a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$keyword})&amp;category=({$category})&amp;orderby=({$orderby})&amp;page=({$page+1})">次を表示</a></p>({/if})
     60({if $is_next})<p class="next"><a href="({t_url m=pc a=page_h_review_search})&amp;keyword=({$smarty.capture.keyword_url|smarty:nodefaults})&amp;category=({$category})&amp;orderby=({$orderby})&amp;page=({$page+1})">次を表示</a></p>({/if})
    5961</div>
    6062({/strip})({/capture})
    6163({$smarty.capture.pager|smarty:nodefaults})
  • webapp/modules/admin/lib/db_admin.php

     
    654654    }
    655655
    656656    //最終ログイン時間で絞り込み
     657    if ($GLOBALS['_OPENPNE_DSN_LIST']['main']['dsn']['phptype'] == 'mysql') {
     658        $no_login_param = '0000-00-00 00:00:00';
     659    } elseif ($GLOBALS['_OPENPNE_DSN_LIST']['main']['dsn']['phptype'] == 'pgsql') {
     660        $no_login_param = '0000-01-01 00:00:00';
     661    }
    657662    if (isset($cond_list['last_login'])) {
    658663        switch($cond_list['last_login']) {
    659664        case 1 : // 3日以内
     
    672677            break;
    673678        case 4 : // 30日以上
    674679            $wheres[] = 'access_date > ? AND access_date < ?';
    675             $params[] = '0000-00-00 00:00:00';
     680            $params[] = $no_login_param;
    676681            $params[] = date('Y-m-d', strtotime('-30 day'));
    677682            break;
    678683        case 5 : // 未ログイン
    679684            $wheres[] = 'access_date = ?';
    680             $params[] = '0000-00-00 00:00:00';
     685            $params[] = $no_login_param;
    681686            break;
    682687        }
    683688    }
  • webapp/modules/admin/templates/topic_list.tpl

     
    116116<tr>
    117117<th>ファイル</th>
    118118<td class="textbody">
    119 <a href="./?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$item.filename})&amp;sessid=({$PHPSESSID})">
     119<a href="./?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$item.filename})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">
    120120({$item.original_filename})
    121121</a>
    122122</td>
  • webapp/modules/admin/templates/delete_topic_comment.tpl

     
    7575<tr>
    7676<th>ファイル</th>
    7777<td class="textbody">
    78 <a href="?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$topic_comment.filename})&amp;sessid=({$PHPSESSID})">
     78<a href="?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$topic_comment.filename})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">
    7979({$topic_comment.original_filename})
    8080</a>
    8181</td>
  • webapp/modules/admin/templates/delete_topic.tpl

     
    7575<tr>
    7676<th>ファイル</th>
    7777<td class="textbody">
    78 <a href="./?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$topic.filename})&amp;sessid=({$PHPSESSID})">
     78<a href="./?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$topic.filename})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">
    7979({$topic.original_filename})
    8080</a>
    8181</td>
  • webapp/modules/admin/templates/csv_download.tpl

     
    2424<input type="hidden" name="start_id" value="0" />
    2525<input type="hidden" name="end_id" value="0" />
    2626<input type="hidden" name="allflag" value="1" />
     27<input type="hidden" name="timestamp" value="({$smarty.now})" />
    2728<p class="textBtn"><input type="submit" value="ダウンロード" /></p>
    2829</form>
    2930
     
    3536<input type="hidden" name="sessid" value="({$PHPSESSID})" />
    3637<input class="basic" type="text" name="start_id" value="" size="5" /> ~ <input class="basic" type="text" name="end_id" value="" size="5" />
    3738<input type="hidden" name="allflag" value="0" />
     39<input type="hidden" name="timestamp" value="({$smarty.now})" />
    3840<p class="textBtn"><input type="submit" value="ダウンロード" /></p>
    3941</form>
    4042
  • webapp/modules/admin/templates/topic_comment_list.tpl

     
    116116<tr>
    117117<th>ファイル</th>
    118118<td class="textbody">
    119 <a href="?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$item.filename})&amp;sessid=({$PHPSESSID})">
     119<a href="?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$item.filename})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">
    120120({$item.original_filename})
    121121</a>
    122122</td>
  • webapp/modules/admin/templates/list_c_file.tpl

     
    6060</td>
    6161({****})
    6262<td>
    63 <a href="./?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$item.filename})&amp;sessid=({$PHPSESSID})">
     63<a href="./?m=({$module_name})&amp;a=do_({$hash_tbl->hash('file_download','do')})&amp;filename=({$item.filename})&amp;sessid=({$PHPSESSID})&amp;({$smarty.now})">
    6464({$item.filename})
    6565</a>
    6666</td>
  • webapp/modules/ktai/templates/fh_diary_list.tpl

     
    3737</table>
    3838({if $is_prev || $is_next})
    3939<center>
    40 ({if $is_prev})<a href="({t_url m=ktai a=page_fh_diary_list})&amp;target_c_member_id=({$target_c_member.c_member_id})&amp;page=({$page-1})({if $keyword})&amp;keyword=({$keyword})({/if})&amp;({$tail})" accesskey="4">[i:128]前を表示</a>({/if})
     40({if $is_prev})<a href="({t_url m=ktai a=page_fh_diary_list})&amp;target_c_member_id=({$target_c_member.c_member_id})&amp;page=({$page-1})({if $keyword})&amp;keyword=({$keyword|to_sjis|escape:url|smarty:nodefaults})({/if})&amp;({$tail})" accesskey="4">[i:128]前を表示</a>({/if})
    4141({if $is_prev && $is_next})&nbsp;({/if})
    42 ({if $is_next})<a href="({t_url m=ktai a=page_fh_diary_list})&amp;target_c_member_id=({$target_c_member.c_member_id})&amp;page=({$page+1})({if $keyword})&amp;keyword=({$keyword})({/if})&amp;({$tail})" accesskey="6">[i:130]次を表示</a>({/if})
     42({if $is_next})<a href="({t_url m=ktai a=page_fh_diary_list})&amp;target_c_member_id=({$target_c_member.c_member_id})&amp;page=({$page+1})({if $keyword})&amp;keyword=({$keyword|to_sjis|escape:url|smarty:nodefaults})({/if})&amp;({$tail})" accesskey="6">[i:130]次を表示</a>({/if})
    4343<br>
    4444</center>
    4545({/if})
  • webapp/modules/ktai/templates/h_message_box.tpl

     
    4747({capture name="pager"})
    4848({if $is_prev_r || $is_next_r})
    4949<center>
    50 ({if $is_prev_r})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=inbox&amp;page_r=({$page_r-1})({if $keyword})&amp;keyword=({$keyword})({/if})&amp;({$tail})" accesskey="4">[i:128]前を表示</a> ({/if})
    51 ({if $is_next_r})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=inbox&amp;page_r=({$page_r+1})({if $keyword})&amp;keyword=({$keyword})({/if})&amp;({$tail})" accesskey="6">[i:130]次を表示</a>({/if})
     50({if $is_prev_r})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=inbox&amp;page_r=({$page_r-1})({if $keyword})&amp;keyword=({$keyword|to_sjis|escape:url|smarty:nodefaults})({/if})&amp;({$tail})" accesskey="4">[i:128]前を表示</a> ({/if})
     51({if $is_next_r})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=inbox&amp;page_r=({$page_r+1})({if $keyword})&amp;keyword=({$keyword|to_sjis|escape:url|smarty:nodefaults})({/if})&amp;({$tail})" accesskey="6">[i:130]次を表示</a>({/if})
    5252</center>
    5353({/if})
    5454({/capture})
     
    7272({capture name="pager"})
    7373({if $is_prev_s || $is_next_s})
    7474<center>
    75 ({if $is_prev_s})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=outbox&amp;page_s=({$page_s-1})({if $keyword})&amp;keyword=({$keyword})({/if})&amp;({$tail})" accesskey="4">[i:128]前を表示</a> ({/if})
    76 ({if $is_next_s})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=outbox&amp;page_s=({$page_s+1})({if $keyword})&amp;keyword=({$keyword})({/if})&amp;({$tail})" accesskey="6">[i:130]次を表示</a>({/if})
     75({if $is_prev_s})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=outbox&amp;page_s=({$page_s-1})({if $keyword})&amp;keyword=({$keyword|to_sjis|escape:url|smarty:nodefaults})({/if})&amp;({$tail})" accesskey="4">[i:128]前を表示</a> ({/if})
     76({if $is_next_s})<a href="({t_url m=ktai a=page_h_message_box})&amp;box=outbox&amp;page_s=({$page_s+1})({if $keyword})&amp;keyword=({$keyword|to_sjis|escape:url|smarty:nodefaults})({/if})&amp;({$tail})" accesskey="6">[i:130]次を表示</a>({/if})
    7777</center>
    7878({/if})
    7979({/capture})
  • webapp/version.php

     
    1 <?php define('OPENPNE_VERSION', '2.12.12'); ?>
     1<?php define('OPENPNE_VERSION', '2.12.13'); ?>
Note: See TracBrowser for help on using the repository browser.