ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
2026-09-12 15:08:24
Editing: ResourceAccess.php
Cancel
Save Changes
<?php /** * Class represents records from table resource_access * {autogenerated} * @property int $resource_access_id * @property int $resource_id * @property string $resource_type * @property string $fn enum('product_id','product_category_id','free') * @property int $id * @property int $start_days * @property int $stop_days * @see Am_Table */ class ResourceAccess extends Am_Record { const FN_PRODUCT = 'product_id'; const FN_CATEGORY = 'product_category_id'; const FN_FREE = 'free'; const FN_FREE_WITHOUT_LOGIN = 'free_without_login'; // resource_id types const FOLDER = 'folder'; const PAGE = 'page'; const LINK = 'link'; const FILE = 'file'; const VIDEO = 'video'; const AUDIO = 'audio'; const INTEGRATION = 'integration'; // plugin name must be appened const EMAILTEMPLATE = 'emailtemplate'; /** * By default includes: FOLDER, PAGE, LINK, FILE, VIDEO */ const USER_VISIBLE_TYPES = 'user-visible-types'; /** * By default includes: FOLDER, PAGE, LINK */ const USER_VISIBLE_PAGES = 'user-visible-pages'; const ANY_PRODUCT = -1; // special category constant public function getId() { return $this->id; } public function getClass() { return $this->fn; } public function getClassTitle() { switch ($this->fn) { case self::FN_FREE : return ___('Free'); case self::FN_FREE_WITHOUT_LOGIN : return ___('Free'); case self::FN_CATEGORY : return ___('Category'); case self::FN_PRODUCT : return ___('Product'); default: return $this->fn; }; } public function getTitle() { if ($this->fn == self::FN_FREE) return ___('Free Access'); if ($this->fn == self::FN_FREE_WITHOUT_LOGIN) return ___('Free Access without log-in'); $pr = null; if ($this->id) { if ($this->fn == self::FN_PRODUCT) $pr = $this->getDi()->productTable->load($this->id, false); elseif ($this->fn == self::FN_CATEGORY) { if ($this->id == self::ANY_PRODUCT) return ___('Any product'); else $pr = $this->getDi()->productCategoryTable->load($this->id, false); } } if (!$pr) return sprintf('(%s #%d)', $this->getClass(), $this->getId()); return $pr->title; } public function getStart() { return strlen($this->start_days) ? "{$this->start_days}d" : null; } public function getStop($parse_forever = true) { if ($this->stop_days == -1 && $parse_forever) return "forever"; return strlen($this->stop_days) ? "{$this->stop_days}d" : null; } public function hasCustomStartStop() { return strlen($this->stop_day) || strlen($this->start_day); } public function isAnyProducts() { return empty($this->product_id) && @$this->product_category_id <= 0; } public function isFree() { return ($this->fn == self::FN_FREE) || ($this->fn == self::FN_FREE_WITHOUT_LOGIN); } } class ResourceAccessTable extends Am_Table { protected $_key = 'resource_access_id'; protected $_table = '?_resource_access'; protected $_recordClass = 'ResourceAccess'; /** * @return Am_Query */ protected function _getBaseQuery($joinConditions = "") { if ($joinConditions) $joinConditions = "(" . $joinConditions . ") AND "; $q = new Am_Query($this, 'r'); $q->clearFields(); $q->addField('DISTINCT r.resource_id', 'resource_id'); $q->addField('resource_type', 'resource_type'); $q->leftJoin("?_access_cache", "c", " $joinConditions (((c.fn = r.fn) AND (c.id = r.id)) OR (r.fn='product_category_id' AND r.id=-1)) AND ( (c.status='active' AND r.start_days IS NULL AND r.stop_days IS NULL) OR (c.status='active' AND c.days BETWEEN IFNULL(r.start_days,0) AND IFNULL(r.stop_days, 90000)) OR (c.days >= IFNULL(r.start_days,0) AND r.stop_days = -1) )"); // is available if free, or if user has equal subscription record in access_cache $q->addWhere("(r.fn IN ('free', 'free_without_login') OR c.user_id IS NOT NULL)"); return $q; } /** * Return resources currently allowed for user * @param User $user * @param array|single type constant from ResourceAccess $types * @return array of records (as array) */ function selectAllowedResources(User $user, $types = null) { // select product_id/product_category_id, type, number of days $q = $this->_getBaseQuery("c.user_id=".intval($user->pk())); if ($types !== null) $q->addWhere("resource_type IN (?a)", is_array($types) ? $types : array($types)); return $this->_db->fetchRows($q->query()); } /** * Return allowed resources as objects * @return array of ResourceAbstract * @see self::selectAllowedResources */ function getAllowedResources(User $user, $types = null, $groupByType = true) { $ret = array(); if ($types === ResourceAccess::USER_VISIBLE_TYPES) $types = array( ResourceAccess::FOLDER, ResourceAccess::FILE, ResourceAccess::PAGE, ResourceAccess::LINK, ResourceAccess::VIDEO, ); elseif ($types === ResourceAccess::USER_VISIBLE_PAGES) $types = array( ResourceAccess::FOLDER, ResourceAccess::PAGE, ResourceAccess::LINK, ); $res = $this->selectAllowedResources($user, $types); usort($res, array($this, '_sortByResourceType')); foreach ($res as $r) { $o = $this->getDi()->getService(lcfirst(toCamelCase($r['resource_type'])) . 'Table')->load($r['resource_id'], false); if ($o) $ret[] = $o; } /** @todo - optimize: load resources by same type with one query */ return $ret; } private function _sortByResourceType($a, $b) { $pri = array( ResourceAccess::FOLDER => 3, ResourceAccess::PAGE => 2, ResourceAccess::FILE => 1, ); $pria = intval(@$pri[$a['resource_type']]); $prib = intval(@$pri[$b['resource_type']]); return -strcmp($pria, $prib); } function userHasAccess(User $user, $id, $type) { $q = $this->_getBaseQuery("c.user_id=".intval($user->pk())); $q->addWhere("resource_type=?", $type); $q->addWhere("resource_id=?", $id); return (bool)$q->selectPageRecords(0, 1); } /** * Return true if not logged-in visitor has access * to the resource */ function guestHasAccess($id, $type) { return (bool)$this->_db->selectCell("SELECT resource_access_id FROM {$this->_table} WHERE resource_type=? AND resource_id=?d AND fn=?", $type, $id, ResourceAccess::FN_FREE_WITHOUT_LOGIN); } function updateCache($userId = null) { if ($userId === null) { $this->_db->query("ALTER TABLE ?_access_cache DISABLE KEYS"); $this->_db->query("TRUNCATE TABLE ?_access_cache"); } else $this->_db->query("DELETE FROM ?_access_cache {WHERE user_id=?d}", $userId ? $userId : DBSIMPLE_SKIP); $productCatsCache = $this->getDi()->productCategoryTable->getCategoryProducts(); $dat = $this->getDi()->sqlDate; $today = $this->getDi()->sqlDate; $q = $this->_db->queryResultOnly(" SELECT user_id, product_id, UNIX_TIMESTAMP(begin_date) AS begin_date, UNIX_TIMESTAMP(LEAST(?, expire_date)) AS expire_date ,begin_date AS sql_begin_date ,expire_date AS sql_expire_date FROM ?_access WHERE {user_id = ?d AND } begin_date <= ? ORDER BY user_id ", $this->getDi()->sqlDate, $userId ? $userId : DBSIMPLE_SKIP, $this->getDi()->sqlDate); $rows = array(); $insert = array(); $lastUserId = null; while ($r = $this->_db->fetchRow($q)) { if (($r['user_id'] != $lastUserId) && $rows) { $insert = array_merge($insert, $this->_updateCacheUser($rows, $productCatsCache, $dat, $today)); if (count($insert) > 100) { $this->_insertCache($insert); $insert = array(); } $rows = array(); } $rows[] = $r; $lastUserId = $r['user_id']; } $this->_db->freeResult($q); if ($rows) $insert = array_merge($insert, $this->_updateCacheUser($rows, $productCatsCache, $dat, $today)); if ($insert) $this->_insertCache($insert); if ($userId === null) { $this->_db->query("ALTER TABLE ?_access_cache ENABLE KEYS"); } } function _insertCache(array $insert) { // todo - direct query : disable _expandPlaceholdersCallback $prefix = $this->_db->getPrefix(); $this->_db->queryQuick("INSERT INTO {$prefix}access_cache (user_id, fn, id, days, begin_date, expire_date, status) VALUES\n" . implode(",", $insert)); } function _updateCacheUser(array $rows, array $productCatsCache, $dat, $today) { $active = $insert = array(); $min = $max = array(); foreach ($rows as $r) { $pid = $r['product_id']; $dates[$pid][] = array($r['begin_date']+43200, 0); $dates[$pid][] = array($r['expire_date']+43200, 1); if (empty($min[$pid]) || ($min[$pid] > $r['sql_begin_date'])) $min[$pid] = $r['sql_begin_date']; if (empty($max[$pid]) || ($max[$pid] < $r['sql_expire_date'])) $max[$pid] = $r['sql_expire_date']; if (($r['sql_begin_date'] <= $today) && ($today <= $r['sql_expire_date'])) { $active[$r['product_id']] = "active"; } elseif (empty($active[$r['product_id']])) { $active[$r['product_id']] = "expired"; } } $len = array(); foreach ($dates as $pid => $d) { sort($dates[$pid]); $len[$pid] = $this->_calcKleeLen($dates[$pid]); $insert[] = sprintf("(%d,'product_id',%d,%d,'%s','%s','%s')", $r['user_id'], $pid, $len[$pid], $min[$pid], $max[$pid], $active[$pid] ); } foreach ($productCatsCache as $pc => $pids) { $catDates = array(); $catActive = 'expired'; $catMax = $catMin = array(); foreach ($pids as $pid) { if (!empty($dates[$pid])) { $catDates = array_merge($catDates, $dates[$pid]); if ($active[$pid] == 'active') $catActive = 'active'; $catMin[$pid] = $min[$pid]; $catMax[$pid] = $max[$pid]; } } if (!$catDates) continue; if (count($catMax) == 1) // if there's only one product found { $pid = key($catMax); $insert[] = sprintf("(%d,'product_category_id',%d,%d,'%s','%s','%s')", $r['user_id'], $pc, $len[$pid], $min[$pid], $max[$pid], $active[$pid]); } else { sort($catDates); $insert[] = sprintf("(%d,'product_category_id',%d,%d,'%s','%s','%s')", $r['user_id'], $pc, $this->_calcKleeLen($catDates), min($catMin), max($catMax), $catActive ); } } return $insert; } function _calcKleeLen($datesArray) { $len = 0; $c = 0; foreach ($datesArray as $i => $v) { if ($c && $i) // count only inside an interval { $len += $v[0] - $datesArray[$i-1][0]; } if ($v[1]) // if end --$c; // we have finished an interval else { if (!$c) // opens new interval $len += 86400; ++$c; // we have started a new interval } } return round($len/86400); } /** * select resource accessible for customers using * records (user_id, resource_id, resource_type, login, email) * @return Am_Query */ function getResourcesForMembers($types = null, $condition="1=1") { if ($types && !is_array($types)) $types = (array)$types; $qfree = new Am_Query($this, 'rfree'); $qfree->crossJoin('?_user', 'u') ->clearFields() ->addField('u.user_id') ->addField('rfree.resource_id') ->addField('rfree.resource_type') ->addField('u.login') ->addField('u.email') ->groupBy('user_id, resource_id, resource_type', 'u') ->addWhere("rfree.fn IN ('free', 'free_without_login')") ->addWhere("( (rfree.start_days IS NULL AND rfree.stop_days IS NULL) OR (CEIL((UNIX_TIMESTAMP() - UNIX_TIMESTAMP(u.added))/86400) BETWEEN IFNULL(rfree.start_days,0) AND IFNULL(rfree.stop_days, 90000)) OR (CEIL((UNIX_TIMESTAMP() - UNIX_TIMESTAMP(u.added))/86400) >= IFNULL(rfree.start_days,0) AND rfree.stop_days = -1) )"); if ($types) $qfree->addWhere('rfree.resource_type IN (?a) AND ' . $condition, $types); $q = $this->_getBaseQuery(); $q->clearFields(); $q->addField('DISTINCT c.user_id') ->addField('r.resource_id') ->addField('r.resource_type') ->addField('u.login') ->addField('u.email') ->leftJoin('?_user', 'u', 'u.user_id=c.user_id') ->addOrder('user_id') ->groupBy('user_id, resource_id, resource_type', 'c') // we will use separate query for free records ->addWhere("r.fn NOT IN ('free', 'free_without_login')") ->addUnion($qfree); if ($types) $q->addWhere('r.resource_type IN (?a) AND ' . $condition, $types); return $q; } function getFnValues() { return array( ResourceAccess::FN_CATEGORY, ResourceAccess::FN_PRODUCT, ResourceAccess::FN_FREE, ResourceAccess::FN_FREE_WITHOUT_LOGIN, ); } }
Upload Files
Cancel
Upload
Create New
Cancel
Create
Change Permissions
Cancel
Save
Change Date
Cancel
Save
Rename Item
Cancel
Save
Confirm Delete
Are you sure you want to delete the selected items?
Cancel
Delete