ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
2026-09-12 20:54:58
Editing: Databased.php
Cancel
Save Changes
<?php /** * Class represents an "integration" plugin for aMember * It will add, remove and update records in third-party script users tables * @package Am_Protect * * Special methods: * @method array parseExternalConfig(string $path) * * return array of config variables parsed from third-party script config * * Accept path to external script as argument. * * throw Am_Exception if path is not correct or unable to parse config. * * <b>Return example:</b> * * array( 'db' => 'MYSQL_DBNAME', * 'user' => 'MYSQL_USER', * 'prefix'=> 'MYSQL_PREFIX' * ) */ abstract class Am_Protect_Databased extends Am_Protect_Abstract implements Am_Protect_SingleLogin { const USER_NEED_SETPASS = 'user_need_setpass'; protected $_tableClass = "Am_Protect_Table"; /** @var Am_Protect_Table */ public $_table = null; /** @var DbSimple_Mysql */ public $_db; /** @var IntegrationTable */ public $_integrationTable; /** @var UserTable */ public $_userTable; /** @var Am_Protect_SessionTable */ public $_sessionTable; /** @var string table name without prefix */ protected $guessTablePattern = null; /** @var array of several fieldnames in the table */ protected $guessFieldsPattern = array( ); protected $groupMode = self::GROUP_NONE; const GROUP_NONE = 0; const GROUP_SINGLE = 1; const GROUP_MULTI = 2; public $sqlDebug = false; protected $skipAfterLogin = false; protected $skipCheckUniqLogin = false; /** @var array group => priority, must be built on first access */ protected $_priority = null; public function __construct(Am_Di $di, array $config) { parent::__construct($di, $config); if ($this->_tableClass === null) $this->_tableClass = get_class($this) . "_Table"; } /** @return IntegrationTable */ public function getIntegrationTable() { if (!$this->_integrationTable) $this->_integrationTable = $this->getDi()->integrationTable; return $this->_integrationTable; } /** @return UserTable */ public function getUserTable() { if (!$this->_userTable) $this->_userTable = $this->getDi()->userTable; return $this->_userTable; } public function _getTableClass() { return $this->_tableClass; } function onSetupForms(Am_Event_SetupForms $event) { $f = new Am_Form_Setup_ProtectDatabased($this); if($plugin_readme = $this->getReadme()) { $plugin_readme = str_replace( array('%root_url%', '%root_surl%', '%root_dir%'), array(ROOT_URL, ROOT_SURL, ROOT_DIR), $plugin_readme); $f->addEpilog('<div class="info"><pre>'.$plugin_readme.'</pre></div>'); } $event->addForm($f); // addConfigItems will be called when necessary } function afterAddConfigItems(Am_Form_Setup_ProtectDatabased $form) { } function guessDbPrefix(DbSimple_Mysql $db, $database=null, $prefix=null) { $res = array(); foreach ($dbs = $db->selectCol("SHOW DATABASES") as $dbname) { try { $tables = $db->selectCol("SHOW TABLES FROM ?# LIKE '%$this->guessTablePattern'", $dbname); } catch (Am_Exception_Db $e) { continue; } if (is_array($tables)) foreach ($tables as $t) { // check fields here $info = $db->select("SHOW COLUMNS FROM `$dbname`.$t"); $infostr = ""; if (is_array($info)) foreach ($info as $k => $v) $infostr .= join(';', $v) . "\n"; $wrong = 0; foreach ($this->guessFieldsPattern as $pat) { if (!preg_match('|^' . $pat . '|m', $infostr)) $wrong++; } if ($wrong) continue; $res[] = $dbname . '.' . substr($t, 0, -strlen($this->guessTablePattern)); } } return $res; } /** @return bool true if plugin is able to create customers without signup */ public function canAutoCreate() { return false; } function configCheckDbSettings(array $config) { $class = get_class($this); $np = new $class($this->getDi(), $config); try { $db = $np->getDb(); } catch (Am_Exception_PluginDb $e) { return "Cannot connect to database, check hostname,username and password settings " . $e->getMessage(); } try { $table = $this->guessTablePattern; $fields = join(',', $this->guessFieldsPattern); $db->query("SELECT $fields FROM ?_{$table} LIMIT 1"); } catch (Am_Exception_PluginDb $e) { $defaultDb = $this->getDi()->getParameter('db'); $defaultDb = $defaultDb['mysql']['db']; $dbname = $config['db'] ? $config['db'] : $defaultDb; $prefix = $config['prefix']; return "Database name or prefix is wrong - could not find table [$prefix{$table}] with fields [$fields] inside database [$dbname]: " . $e->getMessage(); } return $np->configDbChecksAdditional($db); } function configDbChecksAdditional() { } function dbErrorHandler($message, $info) { $class = 'Am_Exception_PluginDb'; $e = new $class("$message({$info['code']}) in query: {$info['query']}", @$info['code']); throw $e; } function getConfigPageId() { return get_first($this->defaultTitle, $this->getId(true)); } public function isConfigured() { return $this->getConfig('db') || $this->getConfig('prefix'); } function getGroupMode() { return $this->groupMode; } function getAdminGroups() { return array_filter(array_map('trim', $this->getConfig('admin_groups', array()))); } function getBannedGroups() { return array_filter(array_map('trim', $this->getConfig('banned_groups', array()))); } /** * Return plugin groups that must be set according to * aMember user subscriptions and aMember configuration * @param User $user if null, defaul group returned * @return array of int third-party group ids, or int for single-group, or true/false for GROUP_NONE */ function calculateGroups(User $user = null, $addDefault = false) { // we have got no user so search does not make sense, return default group if configured $groups = array(); if ($user && $user->pk()) { foreach ($this->getIntegrationTable()->getAllowedResources($user, $this->getId()) as $integration) { $vars = unserialize($integration->vars); $groups[] = $vars; } if ($this->groupMode == self::GROUP_NONE) return (bool) $groups; } else { if ($this->groupMode == self::GROUP_NONE) return false; } $groups = $this->chooseGroups($groups, $user); if ($addDefault && !$groups) { $ret = $this->getConfig('default_group', null); if (($this->groupMode == self::GROUP_MULTI) && (!is_array($ret))) $ret = array($ret); return $ret; } else return $groups; } /** Compare groups based on priority list */ function _compareGroups($a, $b) { $pa = array_key_exists($a, $this->_priority) ? $this->_priority[$a] : 100001; $pb = array_key_exists($b, $this->_priority) ? $this->_priority[$b] : 100000; return $pa - $pb; } /** * * @param type $groups array of configs from ?_integration table * @return array of int|int return sorted array or most suitable single int */ function chooseGroups($groups, User $user = null) { $ret = array(); foreach ($groups as $config) $ret[] = $config['gr']; if ($this->_priority === null) $this->_initPriority(); usort($ret, array($this, '_compareGroups')); if ($this->groupMode == self::GROUP_SINGLE) return $ret ? max($ret) : null; else return $ret; } protected function _initPriority() { $this->_priority = array_flip($this->getConfig('priority', array())); } function getDb() { if (!$this->_db) { $dsn = array(); $dsn['scheme'] = 'mysql'; $dsn['path'] = $this->getConfig('db'); if ($this->getConfig('other_db') == "1") { $dsn = array_merge($dsn, array( 'host' => $this->getConfig('host'), 'user' => $this->getConfig('user'), 'pass' => $this->getConfig('pass'), )); } else { $appOptions = $this->getDi()->getParameters(); $dbConfig = $appOptions['db']['mysql']; $dsn = array_merge($dsn, array( 'host' => $dbConfig['host'], 'user' => $dbConfig['user'], 'pass' => $dbConfig['pass'], )); } if($dsn['host'] && (strpos($dsn['host'], ':') !== false) && preg_match('/\:(\d+)$/',$dns['host'])) list($dsn['host'], $dsn['port']) = explode(':', $dsn['host']); $this->_db = Am_Db::connect($dsn, true); $this->_db->setErrorHandler(array($this, 'dbErrorHandler')); $this->_db->setIdentPrefix($this->getConfig('prefix')); $this->_db->query("USE ?#", $dsn['path']); $this->_db->query("SET NAMES utf8"); $this->_db->query("SET SESSION sql_mode=''"); } if ($this->sqlDebug) { if (!empty($this->getDi()->db->_logger)) $this->_db->setLogger($this->getDi()->db->_logger); } return $this->_db; } function _setDb($db) { $this->_db = $db; } /** lazy-load the table * @return Am_Protect_Table */ function getTable() { if (!$this->_table) $this->_table = $this->createTable()->setDi($this->getDi()); return $this->_table; } /** * create table * you can (in fact you must) override this function to fine-tune * @return Am_Protect_Table */ function createTable() { return new $this->_tableClass($this, $this->getDb()); } /** * create session table if applicable * @return Am_Protect_SingleLogin|null */ function createSessionTable() { return null; } /** * get session table if applicable * @return Am_Protect_SingleLogin|null */ function getSessionTable() { if(!$this->_sessionTable) $this->_sessionTable = $this->createSessionTable(); if(!is_null($this->_sessionTable)) $this->_sessionTable->setDi($this->getDi()); return $this->_sessionTable; } /** * @param Am_Event_SubscriptionChanged $event * @param User $oldUser presents if called from onUserLoginChanged */ function onSubscriptionChanged(Am_Event_SubscriptionChanged $event, User $oldUser = null) { if ($oldUser === null) $oldUser = $event->getUser(); $user = $event->getUser(); $found = $this->getTable()->findByAmember($oldUser); if ($found) { if($this->canUpdate($found)){ $this->getTable()->updateFromAmember($found, $user, $this->calculateGroups($user, true)); $pass = $this->findPassword($user, true); if ($pass) $this->getTable()->updatePassword($found, $pass); } } elseif ($groups = $this->calculateGroups($user, false)) { // we will only insert record if it makes sense - there are groups $this->getTable()->insertFromAmember($user, $this->findPassword($user, true), $groups); } } function onSubscriptionUpdated(Am_Event_SubscriptionUpdated $event) { $e = new Am_Event_SubscriptionChanged($event->getUser(), array(), array()); return $this->onSubscriptionChanged($e, $event->getOldUser()); } function onSubscriptionRemoved(Am_Event_SubscriptionRemoved $event) { $found = $this->getTable()->findByAmember($event->getUser()); if (!$found || !$this->canRemove($found)) return; if ($this->getConfig('remove_users')) { $this->_table->removeRecord($found); } elseif (!$this->isBanned($found)) { $this->_table->disableRecord($found, $this->calculateGroups(null, true)); } } function onSetPassword(Am_Event_SetPassword $event) { $user = $event->getUser(); $found = $this->getTable()->findByAmember($user); if ($found && $this->canUpdate($found)) { $this->_table->updatePassword($found, $event->getSaved($this->getPasswordFormat())); $user->data()->set(self::USER_NEED_SETPASS, null)->update(); } } /** * Return Object that will handle single login. If SessionTable is not created return $this * @return Am_Protect_SingleLogin */ function getSingleLoginObject(){ return is_null($sessionTable = $this->getSessionTable()) ? $this : $sessionTable; } function onAuthCheckLoggedIn(Am_Event_AuthCheckLoggedIn $event) { $record = $this->getSingleLoginObject()->getLoggedInRecord(); if (!$record || !$this->canLogin($record)) return; $user = $this->getTable()->findAmember($record); if (!$user) return; if ($this->getTable()->checkPassword($record, $user)) { $event->setSuccessAndStop($user); $this->skipAfterLogin = true; } } function onAuthAfterLogin(Am_Event_AuthAfterLogin $event) { if ($this->skipAfterLogin) return; $record = $this->getTable()->findByAmember($event->getUser()); if (!$record || !$this->canLogin($record)) return; // there we handled situation when user was added without knowledge of password // @todo implement situation when we have found there is not password // in related user record during login if ($event->getPassword() && $event->getUser()->data()->get(self::USER_NEED_SETPASS)) { $evPass = new Am_Event_SetPassword($event->getUser(), $event->getPassword()); $this->getDi()->savedPassTable->setPass($evPass); $this->getDi()->hook->call($evPass); $event->getUser()->data()->set(self::USER_NEED_SETPASS, null)->update(); $record->refresh(); } if (!$this->getTable()->checkPassword($record, $event->getUser(), $event->getPassword())) return; $this->getSingleLoginObject()->loginUser($record, $event->getPassword()); } function onAuthAfterLogout(Am_Event_AuthAfterLogout $event) { $this->getSingleLoginObject()->logoutUser($event->getUser()); } function onAuthSessionRefresh(Am_Event_AuthSessionRefresh $event){ $afterLoginEvent = new Am_Event_AuthAfterLogin($event->getUser()); $this->onAuthAfterLogin($afterLoginEvent); } function onCheckUniqLogin(Am_Event_CheckUniqLogin $event) { $table = $this->getTable(); if ($table->getIdType() != Am_Protect_Table::BY_LOGIN) return; if ($table->findFirstByLogin($event->getLogin())) $event->setFailureAndStop(); } function onCheckUniqEmail(Am_Event_CheckUniqEmail $event) { $table = $this->getTable(); if ($table->getIdType() != Am_Protect_Table::BY_EMAIL) return; if ($event->getUserId()) { $user = $this->getDi()->userTable->load($event->getUserId()); } else { $user = $this->getDi()->userRecord; $user->email = $event->getEmail(); } $record = $table->findByAmember($user); if ($record) { $user = $table->findAmember($record); if ($user && $user->pk()!=$event->getUserId()) $event->setFailureAndStop(); } } public function onAuthTryLogin(Am_Event_AuthTryLogin $event) { if (!$this->getConfig('auto_create')) return; $login = $event->getLogin(); $isEmail = preg_match('/^.+@.+\..+$/', $login); $found = !$isEmail ? $this->getTable()->findFirstByLogin($login) : $this->getTable()->findFirstByEmail($login); /* @var $found Am_Record */ if (!$found || !$this->canLogin($found)) return; // now create fake user for checkPassword $user = $this->getDi()->userTable->createRecord(); if ($isEmail) $user->email = $login; else $user->login = $login; $user->toggleFrozen(true); if (!$this->getTable()->checkPassword($found, $user, $event->getPassword())) return; // all checked, now create user in aMember $user = $this->getDi()->userRecord; $this->getTable()->createAmember($user, $found); if (!$user->login) { $this->skipCheckUniqLogin = true; $user->generateLogin(); $this->skipCheckUniqLogin = false; } $user->setPass($event->getPassword()); $user->insert(); $event->setCreated($user); } function getLoggedInRecord() { return null; } function loginUser(Am_Record $record, $password) { return false; } function logoutUser(User $user) { } /** * If there is a saved password, return it * If user has plaintext pass set, encrypt it, save and return * if second paramter is true, it will return dummy record * and mark user for password update on next login * @return SavedPass|null */ public function findPassword(User $user, $returnNoPass = false) { // try find password $saved = $this->getDi()->savedPassTable->findSaved($user, $this->getPasswordFormat()); if ($saved) return $saved; /// else encrypt it again $pass = $user->getPlaintextPass(); if ($pass) { $saved = $this->getDi()->savedPassRecord; $saved->user_id = $user->user_id; $saved->format = $this->getPasswordFormat(); $saved->salt = null; $saved->pass = $this->cryptPassword($pass, $saved->salt, $user); $saved->insert(); return $saved; } // nothing if ($returnNoPass) { $pass = $this->getDi()->savedPassRecord; $pass->pass = '-nopass-' . uniqid(); $pass->salt = 'NNN'; if ($user->isLoaded()) $user->data()->set(self::USER_NEED_SETPASS, 1)->update(); return $pass; } } public function isAdmin(Am_Record $record) { if ($this->getGroupMode() == Am_Protect_Databased::GROUP_NONE) return false; return (bool)array_intersect( (array)$this->_table->getGroups($record), $this->getAdminGroups() ); } public function isBanned(Am_Record $record) { if ($this->getGroupMode() == Am_Protect_Databased::GROUP_NONE) return false; return (bool)array_intersect( (array)$this->_table->getGroups($record), $this->getBannedGroups() ); } /** * Return true if we can edit this record, and false if we can not - * for example if it is admin record or a banned record * @return bool */ function canUpdate(Am_Record $record) { return !$this->isAdmin($record) && !$this->isBanned($record); } function canRemove(Am_Record $record) { return !$this->isAdmin($record); } function canLogin(Am_Record $record) { return !$this->isAdmin($record) && !$this->isBanned($record); } function deinstall() { } /** * @see getAvailableUserGroupsSql * @see getManagedUserGroups * @return array Am_Protect_Databased_Usergroup */ function getAvailableUserGroups() { $ret = array(); if ($this->groupMode == self::GROUP_NONE) { $g = new Am_Protect_Databased_Usergroup(array( 'id'=>1, 'title'=>'Registered', 'isAdmin'=>0, 'isBanned'=>0 )); $ret[$g->getId()] = $g; return $ret; } foreach ($this->getDb()->select($this->getAvailableUserGroupsSql()) as $r) { $g = new Am_Protect_Databased_Usergroup($r); $ret[$g->getId()] = $g; } return $ret; } function getAvailableUserGroupsSql() { throw new Am_Exception_NotImplemented("getAvailableUserGroupsSql or getAvailableUserGroups must be redefined"); } /** * return only list of user groups the script must manage: * excluding for example Banned and Admin user groups */ function getManagedUserGroups() { $groups = $this->getAvailableUserGroups(); foreach ($groups as $k => $group) if (in_array($group->getId(), $this->getConfig('admin_groups', array())) || in_array($group->getId(), $this->getConfig('banned_groups', array()))) unset($groups[$k]); return $groups; } public function getIntegrationFormElements(HTML_QuickForm2_Container $container) { $groups = $this->getManagedUserGroups(); $options = array(); foreach ($groups as $g) $options[$g->getId()] = $g->getTitle(); $container ->addSelect('gr', array(), array('options' => $options)) ->setLabel($this->getTitle() . ' usergroup'); } public function getIntegrationSettingDescription(array $config) { $groups = array_combine((array) $config['gr'], (array) $config['gr']); try { foreach ($this->getAvailableUserGroups() as $g) { $id = $g->getId(); if (!empty($groups[$id])) $groups[$id] = '[' . $g->getTitle() . ']'; } } catch (Am_Exception_PluginDb $e) { } return "Assign Group " . implode(",", array_values($groups)); } public function onRebuild(Am_Event_Rebuild $event) { $batch = new Am_BatchProcessor(array($this, 'batchProcess'), 5); $context = $event->getDoneString(); $this->_rebuildName = $this->getId(); $this->_sessionId = Zend_Session::getId(); if ($batch->run($context)) { $event->setDone(); $this->getDi()->storeRebuild->deleteByNameAndSession($this->_rebuildName, $this->_sessionId); } else { $event->setDoneString($context); } } public function batchProcess(&$context, Am_BatchProcessor $batch) { @list($step, $start) = explode('-', $context); $pageCount = 30; switch ($step) { case 0: $q = new Am_Query($this->getTable()); $count = 0; $updated = array(); foreach ($q->selectPageRecords($start / $pageCount, $pageCount) as $r) { $count++; if (!$this->canUpdate($r)) continue; /* @var $r Am_Record */ $user = $this->_table->findAmember($r); if (!$user) { // no such records in aMember, disable user record ? $this->_table->disableRecord($r, $this->calculateGroups(null, true)); } else { $updated[] = $user->user_id; $this->getTable()->updateFromAmember($r, $user, $this->calculateGroups($user, true)); $pass = $this->getDi()->savedPassTable->findSaved($user, $this->getPasswordFormat()); if ($pass) $this->getTable()->updatePassword($r, $pass); } } if (!$count) { $step++; $context = "$step-0"; }else{ $store = array(); foreach ($updated as $v) $store[] = $v; $this->getDi()->storeRebuild->setArray($this->_rebuildName, $this->_sessionId, $store, '+3 hour'); $start += $count; $context = "$step-$start"; } break; case 1: /// now select aMember users not exists in plugin db $count = 0; $db = $this->getDi()->db; $r = $db->queryResultOnly("SELECT t.* from ?_user t left join ?_store_rebuild s on s.user_id = t.user_id and s.rebuild_name = ? and s.session_id = ? WHERE s.user_id is null LIMIT ?d , ?d", $this->_rebuildName, $this->_sessionId, $start , $pageCount); while ($row = $db->fetchRow($r)) { $records[] = $this->getDi()->userTable->createRecord($row); } foreach ($records as $user) { $count++; /* @var $user User */ $this->onSubscriptionChanged(new Am_Event_SubscriptionChanged($user, array(), array())); } if (!$count) { $context = null; return true; } $start += $count; $context = "$step-$start"; break; default: throw new Am_Exception_InputError("Wrong step"); } } } class Am_Protect_Databased_Usergroup { protected $id; protected $title; protected $isAdmin = false; protected $isBanned = false; function __construct($row) { $this->id = $row['id']; $this->title = $row['title']; $this->isAdmin = (bool) @$row['is_admin']; $this->isBanned = (bool) @$row['is_banned']; if (!$this->id) throw new Am_Exception_PluginDb("Wrong group record passed - id is empty"); if (empty($this->title)) throw new Am_Exception_PluginDb("Wrong group record passed - title is empty"); } function isBanned() { return $this->isBanned; } function isAdmin() { return $this->isAdmin; } function getId() { return $this->id; } function getTitle() { return $this->title; } }
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