Advertisement
AE1360

Untitled

Jan 20th, 2020
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 29.12 KB | None | 0 0
  1. <?php
  2. if (!class_exists('Am_Lite', false)) :
  3.  
  4. define('PS_DELIMITER', '|');
  5. define('PS_UNDEF_MARKER', '!');
  6.  
  7. /**
  8.  * Run aMember-related functions without including of entire
  9.  * aMember API stack. Please do not use these functions
  10.  * within aMember itself!
  11.  *
  12.  * @package Am_Lite
  13.  */
  14. class Am_Lite
  15. {
  16.     const PAID = 'paid';
  17.     const FREE = 'free';
  18.     const ANY = 'any';
  19.     const ONLY_LOGIN = 'only_login';
  20.     const ACTIVE = 'active';
  21.     const EXPIRED = 'expired';
  22.     const MAX_SQL_DATE = '2037-12-31';
  23.     const SESSION_NAME = 'PHPSESSID';
  24.  
  25.     const TYPE_SCALAR = 0;
  26.     const TYPE_SERIALIZED = 1;
  27.     const TYPE_BLOB = 16;
  28.     const BLOB_VALUE = 'BLOB_VALUE';
  29.  
  30.     protected static $_instance = null;
  31.     protected $_db_config = null;
  32.     protected $_db = null;
  33.     protected $_session = null;
  34.     protected $_config = null;
  35.     protected $usePHPSessions = false;
  36.     protected $useExceptions = false;
  37.     protected $identity = null;
  38.  
  39.     protected function __construct()
  40.     {
  41.         $this->getDbConfig(); // Read possible defines in config.php
  42.         if (ini_get('suhosin.session.encrypt') || $this->getConfigValue('session_storage')=='php')
  43.             $this->initPHPSession();
  44.     }
  45.  
  46.     protected function initPHPSession()
  47.     {
  48.         $this->usePHPSessions = true;
  49.         if (headers_sent())
  50.         {
  51.             $this->error("Please move <b>require 'Lite.php'</b> line to the top of your file. It should be placed before any html code or php output.");
  52.         }
  53.         @session_name($this->getSessionName());
  54.         @session_start();
  55.     }
  56.  
  57.     /**
  58.      *
  59.      * @return Am_Lite
  60.      */
  61.     static public function getInstance()
  62.     {
  63.         if (is_null(self::$_instance))
  64.         {
  65.             self::$_instance = new self;
  66.         }
  67.         return self::$_instance;
  68.     }
  69.  
  70.     /**
  71.      * shortcut alias for getInstance
  72.      *
  73.      * @return Am_Lite
  74.      */
  75.     static public function i()
  76.     {
  77.         return self::getInstance();
  78.     }
  79.  
  80.     public function setUseExceptions($flag)
  81.     {
  82.         $this->useExceptions = (bool) $flag;
  83.     }
  84.  
  85.     public function isLoggedIn()
  86.     {
  87.         return $this->hasIdentity();
  88.     }
  89.  
  90.     public function getUsername()
  91.     {
  92.         return $this->getUserField('login');
  93.     }
  94.  
  95.     public function getName()
  96.     {
  97.         if ($this->hasIdentity())
  98.         {
  99.             return sprintf("%s %s", $this->getUserField('name_f'), $this->getUserField('name_l'));
  100.         }
  101.         else
  102.         {
  103.             return null;
  104.         }
  105.     }
  106.  
  107.     public function getEmail()
  108.     {
  109.         return $this->getUserField('email');
  110.     }
  111.  
  112.     public function getLogoutURL()
  113.     {
  114.         return $this->getConfigValue('root_surl') . '/logout';
  115.     }
  116.  
  117.     public function getProfileURL()
  118.     {
  119.         return $this->getConfigValue('root_surl') . '/profile';
  120.     }
  121.  
  122.     public function getSendpassURL()
  123.     {
  124.         return $this->getConfigValue('root_surl') . '/login?sendpass';
  125.     }
  126.  
  127.     public function getLoginURL($redirect = null)
  128.     {
  129.         $params = [];
  130.  
  131.         if ($redirect)
  132.             $params['_amember_redirect_url'] = base64_encode($redirect);
  133.  
  134.         if (array_key_exists('_lang', $_GET) && $_GET['_lang'])
  135.             $params['_lang'] = $_GET['_lang'];
  136.  
  137.         $query = http_build_query($params, '', '&');
  138.         return $this->getConfigValue('root_surl')
  139.             . '/login'
  140.             . ($query ? '?' . $query : '');
  141.     }
  142.  
  143.     public function getSignupURL()
  144.     {
  145.         return $this->getConfigValue('root_surl') . '/signup';
  146.     }
  147.  
  148.     public function getRecaptcha()
  149.     {
  150.         $config = $this->getConfig();
  151.         $vals = [
  152.             'recaptcha-public-key',
  153.             'recaptcha-private-key',
  154.             'recaptcha',
  155.             'recaptcha-theme',
  156.             'recaptcha-size',
  157.         ];
  158.         $res = [];
  159.         foreach($vals as $cname) {
  160.             $res[$cname] = @$config[$cname];
  161.         }
  162.         return $res;
  163.     }
  164.  
  165.     public function getModules()
  166.     {
  167.         return $this->getConfigValue('modules');
  168.     }
  169.  
  170.     //added to make old versions working
  171.     public function getRenewURL()
  172.     {
  173.         return $this->getConfigValue('root_surl') . '/signup';
  174.     }
  175.  
  176.     public function renderLoginForm($redirect = null)
  177.     {
  178.         $url = htmlspecialchars($this->getLoginURL(), ENT_QUOTES, 'UTF-8', false);
  179.         $redirect = htmlspecialchars($redirect, ENT_QUOTES, 'UTF-8', false);
  180.         return <<<CUT
  181. <form method="POST" action="$url">
  182.     <label for="form-amember_login">Username/Email</label>
  183.     <input type="text" name="amember_login" id="form-amember_login" />
  184.     <label for="form-amember_pass">Password</label>
  185.     <input type="password" name="amember_pass" id="form-amember_pass" />
  186.     <input type="hidden" name="amember_redirect_url" value="{$redirect}" />
  187.     <input type="submit" value="Login" />
  188. </form>
  189. CUT;
  190.     }
  191.  
  192.     function getRootURL()
  193.     {
  194.         return $this->getConfigValue("root_url");
  195.     }
  196.  
  197.     /**
  198.      * Retrieve logged-in user
  199.      *
  200.      * @return array|null
  201.      */
  202.     public function getUser()
  203.     {
  204.         return $this->getIdentity();
  205.     }
  206.  
  207.     /**
  208.      * Retrieve Affiliate for logged-in user
  209.      *
  210.      * @return array|null
  211.      */
  212.     public function getAffiliate()
  213.     {
  214.         $u = $this->getIdentity();
  215.         if (!$u || !$u['aff_id']) return null;
  216.         $res = $this->query("SELECT * FROM ?_user
  217.            WHERE user_id=? LIMIT 1", $u['aff_id']);
  218.         if ($aff = $res->fetch()) {
  219.             return $this->getFullUserRecord($aff);
  220.         }
  221.         return null;
  222.     }
  223.  
  224.     /**
  225.      * Check if user logged in and have required subscription
  226.      * otherwise redirect to login page or no-access page
  227.      *
  228.      * @param int|array $require product_id or array of product_id or
  229.      * one of special const self::PAID, self:FREE, self::ANY, self::ONLY_LOGIN
  230.      * @param string $title description of protected content,
  231.      * it will be shown at no-access page
  232.      */
  233.     public function checkAccess($require, $title = '')
  234.     {
  235.         if (!$this->hasIdentity())
  236.         {
  237.             header("Location: " . $this->getLoginURL(
  238.                 ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && $_SERVER['HTTPS'] != 'off') ? 'https://' : 'http://') .
  239.                 $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']));
  240.             exit;
  241.         }
  242.  
  243.         if (self::ONLY_LOGIN != $require && !$this->haveSubscriptions($require))
  244.         {
  245.             $params = [
  246.                 'id' => $require,
  247.                 'title' => $title
  248.             ];
  249.  
  250.             header("Location: " . $this->getRootURL() . '/no-access/lite?' . http_build_query($params, '', '&'));
  251.             exit;
  252.         }
  253.     }
  254.  
  255.     /**
  256.      * Whether logged-in user have active subscription or not
  257.      *
  258.      * @param int|array $search
  259.      * @return bool
  260.      */
  261.     public function haveSubscriptions($search = self::ANY)
  262.     {
  263.         if ($this->hasIdentity())
  264.         {
  265.             $accessRecors = $this->_filterNotActiveAccess($this->_getAccessRecords($search));
  266.             return (bool) count($accessRecors);
  267.         }
  268.         else
  269.         {
  270.             return false;
  271.         }
  272.     }
  273.  
  274.     /**
  275.      * Whether logged-in user had active subscription or not
  276.      *
  277.      * @param int|array $search
  278.      * @return bool
  279.      */
  280.     public function hadSubscriptions($search = self::ANY)
  281.     {
  282.         if ($this->hasIdentity())
  283.         {
  284.             $accessRecors = $this->_getAccessRecords($search);
  285.             return (bool) count($accessRecors);
  286.         }
  287.         else
  288.         {
  289.             return false;
  290.         }
  291.     }
  292.  
  293.     /**
  294.      * Retrieve max expire date for selected products
  295.      * for logged-in user
  296.      *
  297.      * @param <type> $search
  298.      * @return string|null date in SQL format YY-mm-dd
  299.      */
  300.     public function getExpire($search = self::ANY)
  301.     {
  302.         $expire = null;
  303.         if ($this->hasIdentity())
  304.         {
  305.             $accessRecors = $this->_getAccessRecords($search);
  306.             foreach ($accessRecors as $access)
  307.             {
  308.                 if ($access['expire_date'] > $expire)
  309.                 {
  310.                     $expire = $access['expire_date'];
  311.                 }
  312.             }
  313.         }
  314.         return $expire;
  315.     }
  316.  
  317.     /**
  318.      * Retrieve the earliest begin date for selected products
  319.      * for logged-in user
  320.      *
  321.      * @param <type> $search
  322.      * @return string|null date in SQL format YY-mm-dd
  323.      */
  324.     public function getBegin($search = self::ANY)
  325.     {
  326.         $begin = self::MAX_SQL_DATE;
  327.         if ($this->hasIdentity())
  328.         {
  329.             $accessRecors = $this->_getAccessRecords($search);
  330.             foreach ($accessRecors as $access)
  331.             {
  332.                 if ($access['begin_date'] < $begin)
  333.                 {
  334.                     $begin = $access['begin_date'];
  335.                 }
  336.             }
  337.         }
  338.         return $begin == self::MAX_SQL_DATE ? null : $begin;
  339.     }
  340.  
  341.     /**
  342.      * Retrieve payments for logged-in user
  343.      *
  344.      * @return array
  345.      */
  346.     public function getPayments()
  347.     {
  348.         $result = [];
  349.         if ($this->hasIdentity())
  350.         {
  351.             $user_id = $this->getUserField('user_id');
  352.             $res = $this->query(
  353.                 'SELECT * FROM ?_invoice_payment
  354.                        WHERE user_id=?', $user_id);
  355.             foreach ($res as $p_rec)
  356.             {
  357.                 $result[] = $p_rec;
  358.             }
  359.         }
  360.         return $result;
  361.     }
  362.  
  363.     public function getUserLinks()
  364.     {
  365.         $sess = $this->getSession();
  366.         return @$sess['amember']['amember_links'];
  367.     }
  368.  
  369.     /**
  370.      * Retrieve access records for logged-in user
  371.      *
  372.      * @return array
  373.      */
  374.     public function getAccess()
  375.     {
  376.         return $this->hasIdentity() ?
  377.             $this->_getAccessRecords(self::ANY) :
  378.             [];
  379.     }
  380.  
  381.     public function getAccessCache()
  382.     {
  383.         return $this->hasIdentity() ?
  384.             $this->_getAccessCache($this->getUserField('user_id')) :
  385.             [];
  386.     }
  387.  
  388.     public function isUserActive()
  389.     {
  390.         $access_cache = $this->getAccessCache();
  391.         foreach ($access_cache as $r)
  392.         {
  393.             if ($r['fn'] == 'product_id' && $r['status'] == self::ACTIVE)
  394.                 return true;
  395.         }
  396.         return false;
  397.     }
  398.  
  399.     public function getProducts($showArchived = true)
  400.     {
  401.         $products = [];
  402.         $res = $this->query("SELECT product_id, title
  403.            FROM ?_product
  404.            WHERE is_archived < ?
  405.            ORDER BY sort_order, title",
  406.             $showArchived ? 2 : 1);
  407.         foreach ($res as $r)
  408.         {
  409.             $products[$r['product_id']] = $r['title'];
  410.         }
  411.         return $products;
  412.     }
  413.  
  414.     public function getCategories()
  415.     {
  416.         $ret = $parents = [];
  417.         $sql = "SELECT product_category_id,
  418.                parent_id, title, code
  419.                FROM ?_product_category
  420.                ORDER BY parent_id, 0+sort_order";
  421.         $rows = $this->query($sql);
  422.  
  423.         foreach ($rows as $id => $r)
  424.         {
  425.             $parents[$r['product_category_id']] = $r;
  426.             $title = $r['title'];
  427.             $parent_id = $r['parent_id'];
  428.             while ($parent_id)
  429.             {
  430.                 $parent = $parents[$parent_id];
  431.                 $title = $parent['title'] . '/' . $title;
  432.                 $parent_id = $parent['parent_id'];
  433.             }
  434.             $ret[$r['product_category_id']] = $title;
  435.         }
  436.         return $ret;
  437.     }
  438.  
  439.     /**
  440.      * Retrieve array of product ids that is member of specific category
  441.      *
  442.      * @param int|array $category_id
  443.      * @return array
  444.      */
  445.     public function getCategoryProducts($category_id)
  446.     {
  447.         $result = [];
  448.  
  449.         $rows = $this->query("SELECT product_id FROM ?_product_product_category
  450.            WHERE product_category_id IN (?)", (array)$category_id);
  451.  
  452.         foreach ($rows as $row)
  453.             $result[] = $row['product_id'];
  454.  
  455.         return $result;
  456.     }
  457.  
  458.     /**
  459.      * Remove not active access from array
  460.      *
  461.      * @param array $access
  462.      * @return array
  463.      */
  464.     protected function _filterNotActiveAccess($access)
  465.     {
  466.         $now = date('Y-m-d');
  467.         foreach ($access as $k => $v)
  468.         {
  469.             if ($v['begin_date'] > $now || $v['expire_date'] < $now)
  470.             {
  471.                 unset($access[$k]);
  472.             }
  473.         }
  474.         return $access;
  475.     }
  476.  
  477.     /**
  478.      * Remove active access from array
  479.      *
  480.      * @param array $access
  481.      * @return array
  482.      */
  483.     protected function _filterActiveAccess($access)
  484.     {
  485.         $now = date('Y-m-d');
  486.         foreach ($access as $k => $v)
  487.         {
  488.             if ($v['begin_date'] <= $now && $v['expire_date'] >= $now)
  489.             {
  490.                 unset($access[$k]);
  491.             }
  492.         }
  493.         return $access;
  494.     }
  495.  
  496.     protected function _getAccessCache($user_id)
  497.     {
  498.         $sql = "SELECT * FROM ?_access_cache where user_id =?";
  499.         $res = $this->query($sql, $user_id);
  500.         $result = [];
  501.         foreach ($res as $r)
  502.         {
  503.             $result[] = $r;
  504.         }
  505.         return $result;
  506.     }
  507.  
  508.     protected function _getAccessRecords($search)
  509.     {
  510.         $result = [];
  511.         $user_id = $this->getUserField('user_id');
  512.         $args = func_get_args();
  513.         if (count($args) == 1 && !is_array($args[0]))
  514.         {
  515.             switch ($args[0])
  516.             {
  517.                 case self::ANY :
  518.                     $sql = "SELECT * FROM ?_access WHERE user_id=?";
  519.                     break;
  520.                 case self::PAID :
  521.                     $sql = "SELECT a.* FROM ?_access a
  522.                            LEFT JOIN ?_invoice_payment p
  523.                            USING(invoice_payment_id)
  524.                            WHERE p.amount>0 AND a.user_id=?";
  525.                     break;
  526.                 case self::FREE :
  527.                     $sql = "SELECT a.* FROM ?_access a
  528.                            LEFT JOIN ?_invoice_payment p
  529.                            USING(invoice_payment_id)
  530.                            WHERE (p.amount=0 OR p.amount IS NULL) AND a.user_id=?";
  531.                     break;
  532.                 default:
  533.                     $sql = sprintf("SELECT * FROM ?_access WHERE user_id=?
  534.                            AND product_id='%d'", $args[0]);
  535.             }
  536.         }
  537.         else
  538.         {
  539.             $p_ids = is_array($args[0]) ? $args[0] : $args;
  540.             $p_ids = array_map('intval', $p_ids);
  541.             $p_ids[] = -1;
  542.  
  543.             $sql = sprintf("SELECT * FROM ?_access WHERE user_id=?
  544.                    AND product_id IN (%s)", implode(',', $p_ids));
  545.         }
  546.  
  547.         $res = $this->query($sql, $user_id);
  548.         foreach ($res as $a_rec)
  549.         {
  550.             $result[] = $a_rec;
  551.         }
  552.  
  553.         return $result;
  554.     }
  555.  
  556.     /**
  557.      *
  558.      * @return PDO
  559.      */
  560.     protected function getDb()
  561.     {
  562.         if (is_null($this->_db))
  563.         {
  564.             $config = $this->getDbConfig();
  565.  
  566.             try
  567.             {
  568.                 if (strpos($config['host'], ':') !== false)
  569.                     list($host, $socket) = @explode(':', $config['host']);
  570.                 else
  571.                 {
  572.                     $host = $config['host'];
  573.                     $socket = '';
  574.                 }
  575.  
  576.                 $this->_db = new PDO($d = 'mysql:host=' . $host .
  577.                         (empty($config['port']) ? '' : ';port=' . $config['port']) .
  578.                         (empty($socket) ? '' : ';unix_socket=' . $socket) .
  579.                         ';dbname=' . $config['db'].';charset=utf8',
  580.                         $config['user'], $config['pass']);
  581.                 $this->_db->query("SET NAMES UTF8");
  582.             }
  583.             catch (Exception $e)
  584.             {
  585.                 $this->error($e);
  586.             }
  587.         }
  588.  
  589.         return $this->_db;
  590.     }
  591.  
  592.     /**
  593.      * Execute SQL query
  594.      *
  595.      * @param string $sql
  596.      * @return PDOStatement
  597.      */
  598.     protected function query($sql, $args = null)
  599.     {
  600.         $db_config = $this->getDbConfig();
  601.         $sql = preg_replace('/(\s)\?_([a-z0-9_]+)\b/', ' ' . $db_config['prefix'] . '\2', $sql);
  602.         $argv = func_get_args();
  603.         array_shift($argv);
  604.         foreach ($argv as & $arg) //skip first value, it is $sql
  605.         {
  606.             if (is_array($arg))
  607.             {
  608.                 $arg = implode(',', array_map([$this->getDb(), 'quote'], $arg));
  609.             } elseif (is_null($arg)) {
  610.                 $arg = 'NULL';
  611.             } else {
  612.                 $arg = $this->getDb()->quote($arg);
  613.             }
  614.         }
  615.         $f = function() use (& $argv) {
  616.             return $argv ? array_shift($argv) : 'LITE_DB_ERROR_NO_VALUE';
  617.         };
  618.         $sql = preg_replace_callback('#\?#', $f, $sql);
  619.         $statement = $this->getDb()->query($sql);
  620.         if (!$statement)
  621.         {
  622.             $errorInfo = $this->getDb()->errorInfo();
  623.             $this->error($errorInfo[2]);
  624.         }
  625.         $statement->setFetchMode(PDO::FETCH_ASSOC);
  626.  
  627.         return $statement;
  628.     }
  629.  
  630.     protected function getDbConfig()
  631.     {
  632.         if (is_null($this->_db_config))
  633.         {
  634.             $file = dirname(__FILE__) . '/../../application/configs/config.php';
  635.             if (!file_exists($file))
  636.             {
  637.                 $this->error('!!!! Can not find file with aMember config - ' . $file);
  638.             }
  639.             $config = @include($file);
  640.             if (!is_array($config))
  641.             {
  642.                 $this->error('aMember config should return array');
  643.             }
  644.             $this->_db_config = $config['db']['mysql'];
  645.         }
  646.         return $this->_db_config;
  647.     }
  648.  
  649.     protected function getConfig()
  650.     {
  651.         if (!is_null($this->_config)) {
  652.             return $this->_config;
  653.         }
  654.  
  655.         if(defined('AM_CONFIG_NAME') && AM_CONFIG_NAME) {
  656.             $name = AM_CONFIG_NAME;
  657.         } else {
  658.             $name = 'default';
  659.         }
  660.  
  661.         $res = $this->query("SELECT config FROM ?_config WHERE name=?", $name);
  662.         $config = $res->fetch();
  663.         return $this->_config = unserialize($config['config']);
  664.     }
  665.  
  666.     protected function getConfigValue($name)
  667.     {
  668.         $config = $this->getConfig();
  669.         return isset($config[$name]) ? $config[$name] : null;
  670.     }
  671.  
  672.     protected function getLoginCookie($u) {
  673.         return sha1($u['user_id'].$u['login'].md5($u['pass']).$u['remember_key']);
  674.     }
  675.  
  676.     protected function getFullUserRecord($u)
  677.     {
  678.         $data = [];
  679.         $result = $this->query('SELECT `key`, `type`,
  680.            CASE `type`
  681.                WHEN ? THEN NULL
  682.                WHEN ? THEN `blob`
  683.                ELSE `value`
  684.            END AS "value"
  685.            FROM ?_data WHERE `table`=? AND `id`=?
  686.            ', self::TYPE_BLOB, self::TYPE_SERIALIZED, 'user', $u['user_id']);
  687.         foreach ($result as $arr)
  688.         {
  689.             switch ($arr['type'])
  690.             {
  691.                 case self::TYPE_SCALAR: $data[$arr['key']] = $arr['value'];
  692.                     break;
  693.                 case self::TYPE_SERIALIZED: $data[$arr['key']] = unserialize($arr['value']);
  694.                     break;
  695.                 case self::TYPE_BLOB: $data[$arr['key']] = self::BLOB_VALUE;
  696.                     break;
  697.                 default:
  698.                     $this->error("Unknown record type {$arr['type']} in ?_data");
  699.             }
  700.         }
  701.  
  702.         return array_merge($data, $u);
  703.  
  704.     }
  705.  
  706.     protected function authenticate()
  707.     {
  708.         if (!is_null($this->identity)) return;
  709.         $this->identity = false;
  710.  
  711.         $session = $this->getSession();
  712.         if (@isset($session['amember_auth']['user'])) {
  713.             $this->identity = $session['amember_auth']['user'];
  714.         } elseif (isset($_COOKIE['amember_ru']) && isset($_COOKIE['amember_rp'])) {
  715.             $login = preg_replace('/[^A-Za-z0-9_-]/', '', (string)$_COOKIE['amember_ru']);
  716.             $pass = preg_replace('/[^A-Za-z0-9_-]/', '', (string)$_COOKIE['amember_rp']);
  717.             $result = $this->query('SELECT * FROM ?_user WHERE login = ?', $login);
  718.             if ($result) {
  719.                 $user = $result->fetch();
  720.                 if ($this->getLoginCookie($user) == $pass) {
  721.                     $this->identity = $this->getFullUserRecord($user);
  722.                 }
  723.             }
  724.         }
  725.     }
  726.  
  727.     protected function hasIdentity()
  728.     {
  729.         $this->authenticate();
  730.         return (bool)$this->identity;
  731.     }
  732.  
  733.     protected function getIdentity()
  734.     {
  735.         return $this->hasIdentity() ?
  736.             $this->identity : null;
  737.     }
  738.  
  739.     protected function getUserField($name)
  740.     {
  741.         if ($this->hasIdentity())
  742.         {
  743.             $user = $this->getIdentity();
  744.             return $user[$name];
  745.         }
  746.         else
  747.         {
  748.             return null;
  749.         }
  750.     }
  751.  
  752.     protected function getPHPSession()
  753.     {
  754.         $this->_session = $_SESSION;
  755.         self::processStartupMetadata($this->_session);
  756.         return $this->_session;
  757.     }
  758.  
  759.     protected function getSession()
  760.     {
  761.         if ($this->usePHPSessions)
  762.         {
  763.             return $this->getPHPSession();
  764.         }
  765.         if (is_null($this->_session))
  766.         {
  767.             $sessionName = $this->getSessionName();
  768.             if(isset($_COOKIE[$sessionName]) && !empty($_COOKIE[$sessionName]))
  769.             {
  770.                 $session_id = preg_replace('/[^A-Za-z0-9_,-]/', '', (string)$_COOKIE[$sessionName]);
  771.                 /** @var $res PDOStatement */
  772.                 $res = $this->query(
  773.                     sprintf("SELECT * FROM ?_session WHERE id=? AND (%s - modified) < lifetime", time()), $session_id);
  774.  
  775.                 $session = $res->fetch();
  776.                 $this->_session = $session ?
  777.                     self::unserializeSession($session['data']) :
  778.                     [];
  779.             }
  780.             else
  781.             {
  782.                 $this->_session = [];
  783.             }
  784.             self::processStartupMetadata($this->_session);
  785.         }
  786.         return $this->_session;
  787.     }
  788.  
  789.     /**
  790.      * remove expired namespaces and variables
  791.      *
  792.      * @see Zend_Session::_processStartupMetadataGlobal
  793.      * @param array $session
  794.      */
  795.     static function processStartupMetadata(&$session)
  796.     {
  797.         if (isset($session['__ZF']))
  798.         {
  799.             foreach ($session['__ZF'] as $namespace => $namespace_metadata)
  800.             {
  801.                 // Expire Namespace by Time (ENT)
  802.                 if (isset($namespace_metadata['ENT']) && ($namespace_metadata['ENT'] > 0) && (time() > $namespace_metadata['ENT']))
  803.                 {
  804.                     unset($session[$namespace]);
  805.                     unset($session['__ZF'][$namespace]);
  806.                 }
  807.  
  808.                 // Expire Namespace Variables by Time (ENVT)
  809.                 if (isset($namespace_metadata['ENVT']))
  810.                 {
  811.                     foreach ($namespace_metadata['ENVT'] as $variable => $time)
  812.                     {
  813.                         if (time() > $time)
  814.                         {
  815.                             unset($session[$namespace][$variable]);
  816.                             unset($session['__ZF'][$namespace]['ENVT'][$variable]);
  817.                         }
  818.                     }
  819.                     if (empty($session['__ZF'][$namespace]['ENVT']))
  820.                     {
  821.                         unset($session['__ZF'][$namespace]['ENVT']);
  822.                     }
  823.                 }
  824.             }
  825.         }
  826.     }
  827.  
  828.     /**
  829.      *
  830.      * @param string $data session encoded
  831.      * @return array
  832.      */
  833.     static function unserializeSession($str)
  834.     {
  835.         $str = (string) $str;
  836.  
  837.         $endptr = strlen($str);
  838.         $p = 0;
  839.  
  840.         $serialized = '';
  841.         $items = 0;
  842.         $level = 0;
  843.  
  844.         while ($p < $endptr)
  845.         {
  846.             $q = $p;
  847.             while ($str[$q] != PS_DELIMITER)
  848.                 if (++$q >= $endptr)
  849.                     break 2;
  850.  
  851.             if ($str[$p] == PS_UNDEF_MARKER)
  852.             {
  853.                 $p++;
  854.                 $has_value = false;
  855.             }
  856.             else
  857.             {
  858.                 $has_value = true;
  859.             }
  860.  
  861.             $name = substr($str, $p, $q - $p);
  862.             $q++;
  863.  
  864.             $serialized .= 's:' . strlen($name) . ':"' . $name . '";';
  865.  
  866.             if ($has_value)
  867.             {
  868.                 for (;;)
  869.                 {
  870.                     $p = $q;
  871.                     switch ($str[$q])
  872.                     {
  873.                         case 'N': /* null */
  874.                         case 'b': /* boolean */
  875.                         case 'i': /* integer */
  876.                         case 'd': /* decimal */
  877.                             do
  878.                                 $q++;
  879.                             while (($q < $endptr) && ($str[$q] != ';'));
  880.                             $q++;
  881.                             $serialized .= substr($str, $p, $q - $p);
  882.                             if ($level == 0)
  883.                                 break 2;
  884.                             break;
  885.                         case 'R': /* reference  */
  886.                         case 'r': /* reference  */
  887.                             $key = $str[$q];
  888.                             $q+= 2;
  889.                             for ($id = ''; ($q < $endptr) && ($str[$q] != ';'); $q++)
  890.                                 $id .= $str[$q];
  891.                             $q++;
  892.                             $serialized .= $key.':' . ($id + 1) . ';'; /* increment pointer because of outer array */
  893.                             if ($level == 0)
  894.                                 break 2;
  895.                             break;
  896.                         case 's': /* string */
  897.                             $q+=2;
  898.                             for ($length = ''; ($q < $endptr) && ($str[$q] != ':'); $q++)
  899.                                 $length .= $str[$q];
  900.                             $q+=2;
  901.                             $q+= (int) $length + 2;
  902.                             $serialized .= substr($str, $p, $q - $p);
  903.                             if ($level == 0)
  904.                                 break 2;
  905.                             break;
  906.                         case 'a': /* array */
  907.                         case 'O': /* object */
  908.                             do
  909.                                 $q++;
  910.                             while (($q < $endptr) && ($str[$q] != '{'));
  911.                             $q++;
  912.                             $level++;
  913.                             $serialized .= substr($str, $p, $q - $p);
  914.                             break;
  915.                         case '}': /* end of array|object */
  916.                             $q++;
  917.                             $serialized .= substr($str, $p, $q - $p);
  918.                             if (--$level == 0)
  919.                                 break 2;
  920.                             break;
  921.                         default:
  922.                             return false;
  923.                     }
  924.                 }
  925.             } else
  926.             {
  927.                 $serialized .= 'N;';
  928.                 $q+= 2;
  929.             }
  930.             $items++;
  931.             $p = $q;
  932.         }
  933.         return @unserialize('a:' . $items . ':{' . $serialized . '}');
  934.     }
  935.  
  936.     /**
  937.      * @return Name of aMember's session variable.
  938.      */
  939.     protected function getSessionName()
  940.     {
  941.         if (defined('AM_SESSION_NAME') && AM_SESSION_NAME)
  942.             return AM_SESSION_NAME;
  943.         else
  944.             return self::SESSION_NAME;
  945.     }
  946.  
  947.     protected function error($msgOrException)
  948.     {
  949.         $msg = is_string($msgOrException) ? $msgOrException : $msgOrException->getMessage();
  950.         $exception = is_string($msgOrException) ? new Exception($msgOrException) : $msgOrException;
  951.  
  952.         if ($this->useExceptions)
  953.         {
  954.             throw $exception;
  955.         }
  956.         else
  957.         {
  958.             $this->amDie($msg);
  959.         }
  960.     }
  961.  
  962.     protected function amDie($msg, $return = false)
  963.     {
  964.         $out = <<<CUT
  965. <!DOCTYPE html>
  966. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  967.     <head>
  968.         <title>Fatal Error</title>
  969.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  970.         <style type="text/css">
  971.         body {
  972.                 background: #eee;
  973.                 font: 80%/100% verdana, arial, helvetica, sans-serif;
  974.                 text-align: center;
  975.         }
  976.         #container {
  977.             display: inline-block;
  978.             margin: 50px auto 0;
  979.             text-align: left;
  980.             border: 2px solid #f00;
  981.             background-color: #fdd;
  982.             padding: 10px 10px 10px 10px;
  983.             width: 60%;
  984.         }
  985.         h1 {
  986.             font-size: 12pt;
  987.             font-weight: bold;
  988.         }
  989.         </style>
  990.     </head>
  991.     <body>
  992.         <div id="container">
  993.             <h1>Script Error</h1>
  994.             $msg
  995.         </div>
  996.     </body>
  997. </html>
  998. CUT;
  999.         if (!$return) {
  1000.             while(@ob_end_clean());
  1001.         }
  1002.         return $return ? $out : exit($out);
  1003.  
  1004.     }
  1005.  
  1006. }
  1007.  
  1008. /*
  1009.  * Init Am_Lite
  1010.  * see constructor for more details;
  1011.  */
  1012.  
  1013. Am_Lite::getInstance();
  1014.  
  1015. endif;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement