v7‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT home/ajdemo/public_html/mempro/application/default/models/User.php000064400000100031152101620240021361 0ustar00email, Am_Mail::LINK_USER); return null; } function __isset($name) { return ($name == 'unsubscribe_link'); } function delete() { if ($this->user_id <= 0) throw new Am_Exception_InternalError('Could not delete user, user_id is null'); $this->getDi()->hook->call(Am_Event::USER_BEFORE_DELETE, array('user' => $this)); $this->getDi()->invoiceTable->deleteByUserId($this->user_id); $this->getDi()->accessTable->deleteByUserId($this->user_id); $this->checkSubscriptions(false); $this->getDi()->hook->call(new Am_Event_SubscriptionRemoved($this)); parent::delete(); foreach (array('?_access_log', '?_access_cache', '?_user_status', '?_user_user_group') as $table) $this->getAdapter()->query("DELETE FROM $table WHERE user_id=?", $this->user_id); $this->getDi()->couponBatchTable->deleteByUserId($this->user_id); foreach ($this->getDi()->uploadTable->findBy(array( 'prefix' => Am_CustomFieldUpload::UPLOAD_PREFIX, 'user_id' => $this->user_id)) as $upload) { $upload->delete(); } $this->getDi()->hook->call(new Am_Event_UserAfterDelete($this)); } function insert($reload = true) { if (!isset($this->is_approved)) $this->is_approved = !$this->getDi()->config->get('manually_approve'); if (empty($this->remote_addr)) $this->remote_addr = htmlentities(@$_SERVER['REMOTE_ADDR']); if (empty($this->user_agent)) $this->user_agent = @$_SERVER['HTTP_USER_AGENT']; if (empty($this->added)) $this->added = $this->getDi()->sqlDateTime; $this->getDi()->hook->call(new Am_Event_UserBeforeInsert($this)); $ret = parent::insert($reload); if ($this->_passwordChanged) { $event = new Am_Event_SetPassword($this, $this->getPlaintextPass()); $this->getDi()->savedPassTable->setPass($event); $this->getDi()->hook->call($event); } if ($this->_passwordGenerated) { $c = new Am_Crypt_Aes128($this->getDi()->security->siteKey()); $pg = $c->encrypt($this->getPlaintextPass()); $this->getDi()->store->set('pass-generated-' . $this->pk(), $pg, '+6 hours'); } $this->getDi()->hook->call(new Am_Event_UserAfterInsert($this)); $this->_passwordChanged = false; return $ret; } function update() { $oldU = new stdclass; $oldU->user_id = null; if ($this->getDi()->hook->have(array( 'userBeforeUpdate', 'userAfterUpdate', 'subscriptionUpdated')) || $this->getDi()->config->get('manually_approve') ) { // do loading only if hooks are set $oldU = $this->getTable()->load($this->user_id, false); if (!$oldU) $oldU = new self; // avoid errors here $this->getDi()->hook->call(new Am_Event_UserBeforeUpdate($this, $oldU)); } $ret = parent::update(); if ($this->_passwordChanged) { $this->data()->set(self::NEED_SESSION_REFRESH, true)->update(); $event = new Am_Event_SetPassword($this, $this->getPlaintextPass()); $this->getDi()->savedPassTable->setPass($event); $this->getDi()->hook->call($event); $this->sendChangepassEmail(); } if ($oldU->user_id) { if ($this->is_approved && !$oldU->is_approved) $this->approve(); $this->getDi()->hook->call(new Am_Event_UserAfterUpdate($this, $oldU)); } if ($this->status && $oldU->user_id) { $this->getDi()->hook->call(new Am_Event_SubscriptionUpdated($this, $oldU)); } $this->_passwordChanged = false; return $ret; } function approve() { foreach ($this->getDi()->invoiceTable->findByUserId($this->pk()) as $invoice) $invoice->approve(); if (!$this->is_approved) { $this->is_approved = 1; $this->save(); } $this->sendSignupEmailIfNecessary(); } protected function _prepareForSet(&$vars) { if (isset($vars['pass'])) unset($vars['pass']); return parent::_prepareForSet($vars); } /** * @param string submitted password * @return bool true if ok, false if not */ function checkPassword($pass) { if (!strlen($pass) || !isset($this->pass) || !strlen($this->pass)) { return false; } $ph = new PasswordHash(8, true); return $ph->CheckPassword($pass, $this->pass); } /** * Set new password * (important! - it does not save the password!) */ function setPass($pass, $quick = false) { $this->_plaintextPass = $pass; $this->_passwordChanged = true; $this->pass = self::cryptPass($pass, $quick); $this->pass_dattm = $this->getDi()->sqlDateTime; return $this; } static function cryptPass($pass, $quick = false) { $ph = new PasswordHash($quick ? 4 : 8, true); return $ph->HashPassword($pass); } /** It is only exists after call of @method setPass() */ function getPlaintextPass() { return $this->_plaintextPass; } function getSavedPass() { return $this->getDi()->savedPassTable->findByUserId($this->pk()); } /** * Load generated password in plain-text format * it is only available 6 hours after signup and * supposed to be displayed on thanks page * * @return string|null */ function getStoredPlaintextPassword() { $pg = $this->getDi()->store->get('pass-generated-' . $this->pk()); if (!$pg) return null; $c = new Am_Crypt_Aes128($this->getDi()->security->siteKey()); return $c->decrypt($pg); } function getLoginCookie() { if (!$this->remember_key) { $this->updateQuick('remember_key', sha1(rand())); } return sha1($this->user_id . $this->login . md5($this->pass) . $this->remember_key); } function generateLogin() { // usernames to try $try = array(); if (!empty($this->email) && preg_match("/^([a-zA-Z0-9_]+)\@/", $this->email, $regs)) $try[] = $regs[1]; $fn = strtolower(preg_replace('/[^\w\d_]/', '', @$this->name_f)); $ln = strtolower(preg_replace('/[^\w\d_]/', '', @$this->name_l)); if ($fn || $ln) { if ($fn && $ln) { $try[] = $fn . '_' . $ln; } else { $try[] = $fn . $ln; } $try[] = $try[count($try) - 1] . rand(100, 999); } $e = new Am_Event(Am_Event::GENERATE_LOGIN, array('user' => $this)); $e->setReturn($try); $this->getDi()->hook->call($e); $try = $e->getReturn(); foreach ($try as $login) { if (strlen($login) > $this->getDi()->config->get('login_max_length')) $login = substr($login, 0, $this->getDi()->config->get('login_max_length')); if ((strlen($login) >= $this->getDi()->config->get('login_min_length')) && $this->getDi()->userTable->checkUniqLogin($login) && !$this->getDi()->banTable->findBan(array('login' => $login))) { $this->login = $login; return $this; } } // will generate it // a bit of configuration $min_length = $this->getDi()->config->get('login_min_length') < 4 ? 4 : $this->getDi()->config->get('login_min_length'); $max_length = $this->getDi()->config->get('login_max_length') > 10 ? 10 : $this->getDi()->config->get('login_max_length'); /// let's go do { $pass = $this->getDi()->security->randomString(rand($min_length, $max_length), "qwertyuiopasdfghjklzxcvbnm"); } while (!$this->getDi()->userTable->checkUniqLogin($pass)); $this->login = $pass; return $this; } function generatePassword() { // a bit of configuration $min_length = max($this->getDi()->config->get('pass_min_length', 8), 8); $max_length = min($this->getDi()->config->get('pass_max_length', 12), 14); $all_g = "aeiyo"; $all_gn = $all_g . "1234567890"; $all_s = "bcdfghjkmnpqrstwxz"; /// let's go $pass = ""; $length = rand($min_length, $max_length); for ($i = 0; $i < $length; $i++) { if ($i % 2) if ($i < $min_length) $pass .= $all_g[rand(0, strlen($all_g) - 1)]; else $pass .= $all_gn[rand(0, strlen($all_gn) - 1)]; else $pass .= $all_s[rand(0, strlen($all_s) - 1)]; } $this->_passwordGenerated = true; $this->setPass($pass); return $this; } private function _trueIfActive($v) { return $v == self::STATUS_ACTIVE; } private function _trueIfExpired($v) { return $v == self::STATUS_EXPIRED; } function checkSubscriptions($updateCache = false) { if (!$this->user_id) throw new Am_Exception_InternalError("Could not do User->checkSubscriptions() : user_id is empty"); if ($updateCache) $this->getDi()->resourceAccessTable->updateCache($this->user_id); $newStatus = $this->getDi()->accessTable->getStatusByUserId($this->user_id); $active = array_keys(array_filter($newStatus, array($this, '_trueIfActive'))); $oldStatus = $this->getProductsStatus(); $saved = array_keys(array_filter($oldStatus, array($this, '_trueIfActive'))); $merged = array_unique(array_merge($active, $saved)); $added = array_diff($merged, $saved); $deleted = array_diff($merged, $active); if ($active) $newUserStatus = self::STATUS_ACTIVE; elseif (array_filter($newStatus, array($this, '_trueIfExpired'))) $newUserStatus = self::STATUS_EXPIRED; else $newUserStatus = self::STATUS_PENDING; $statusChanged = ($newUserStatus != @$this->status); if ($statusChanged) { $this->updateQuick('status', $newUserStatus); } if ($added || $deleted || array_diff_assoc($newStatus, $oldStatus) || array_diff_assoc($oldStatus, $newStatus)) { $this->data()->set(self::NEED_SESSION_REFRESH, true)->update(); $this->getDi()->userStatusTable->setByUserId($this->user_id, $newStatus); foreach ($added as $product_id) { $e = new Am_Event_SubscriptionAdded($this, $this->getDi()->productTable->load($product_id)); $this->getDi()->hook->call($e); } foreach ($deleted as $product_id) { $e = new Am_Event_SubscriptionDeleted($this, $this->getDi()->productTable->load($product_id)); $this->getDi()->hook->call($e); } $e = new Am_Event_SubscriptionChanged($this, $added, $deleted); $this->getDi()->hook->call($e); } if ($statusChanged) { $this->sendSignupEmailIfNecessary(); } } /** * This function is called upon completion of payment * If user signup e-mail was not set before, it will be sent from there * It checks if : * - email is enabled in config * - user has at least one completed payment * - the e-mail was not sent before * - customer was approved */ function sendSignupEmailIfNecessary(InvoicePayment $p = null) { if (!$this->getDi()->config->get('send_signup_mail')) return; if ($this->data()->get('signup_email_sent')) return; // was already sent if (!$this->isApproved()) return; // is not yet approved $this->sendSignupEmail($p); } function sendSignupEmail(InvoicePayment $p = null) { if ($et = Am_Mail_Template::load('send_signup_mail', $this->lang)) { $et->setUser($this); //%password% placeholder will be available only in case auto_create //mode in payment system (user and payment created during same request) $pass = $this->getPlaintextPass(); $et->setPassword($pass ? $pass : ___('what you entered when creating your account')); if (empty($p)) $p = $this->getDi()->invoicePaymentTable->findFirstByUserId($this->user_id); if ($p) $et->setPayment($p); $et->send($this); $this->data()->set('signup_email_sent', 1)->update(); } } function sendRegistrationToAdminEmail() { if ($et = Am_Mail_Template::load('registration_mail_admin')) { $et->setUser($this); $et->setPassword($this->getPlaintextPass()); $et->sendAdmin(); } } function sendRegistrationEmail() { if ($et = Am_Mail_Template::load('registration_mail', $this->lang)) { $et->setUser($this); $et->setPassword($this->getPlaintextPass()); $et->send($this); } } function sendChangepassEmail() { if ($this->getDi()->config->get('changepass_mail') && ($et = Am_Mail_Template::load('changepass_mail', $this->lang))) { $et->setUser($this); $et->setPassword($this->getPlaintextPass()); $et->send($this); } } function sendNotApprovedEmail() { if ($et = Am_Mail_Template::load('manually_approve', $this->lang)) { $et->setUser($this); $et->send($this); } if ($et = Am_Mail_Template::load('manually_approve_admin')) { $et->setUser($this); $et->send(Am_Mail_Template::TO_ADMIN); } } /** * @return bool true if user have any active subscriptions */ function isActive() { return $this->status == self::STATUS_ACTIVE; } /** * Return true if customer paid at least once * @return bool */ function isPaid() { return (bool) $this->getAdapter()->selectCell( "SELECT SUM(amount)>0 FROM ?_invoice_payment p WHERE user_id=?d" , $this->user_id); } /** * @return true if user is approved */ function isApproved() { return!empty($this->is_approved) && ($this->is_approved > 0); } function isLocked() { return!empty($this->is_locked) && ($this->is_locked > 0); } function lock($flag = true) { $this->is_locked = (int)$flag; $this->save(); } /** * @return array of Access objects */ function getAccessRecords() { return $this->getDi()->accessTable->findByUserId($this->user_id); } function getActiveProducts() { return $this->getDi()->productTable->selectObjects("SELECT p.* FROM ?_user_status us " . "LEFT JOIN ?_product p USING(product_id) WHERE user_id=?d " . "AND status=?d " . "AND p.product_id IS NOT NULL " . "ORDER BY sort_order", $this->user_id, self::STATUS_ACTIVE); } function getExpiredProducs() { return $this->getDi()->productTable->loadIds($this->getExpiredProductIds()); } function getFutureProducts() { return $this->getDi()->productTable->loadIds($this->getFutureProductIds()); } /** * Returns max expiration date * if product or array of products are specified, returns it * for given products only */ function getExpire($productIdOrIds = array()) { $productIdOrIds = (array) $productIdOrIds; $productIdOrIds = array_filter(array_map('intval', $productIdOrIds)); return $this->getDi()->db->selectCell("SELECT MAX(expire_date) FROM ?_access WHERE user_id=?d { AND product_id IN (?a) }", $this->pk(), $productIdOrIds ? $productIdOrIds : DBSIMPLE_SKIP ); } function getBegin($productIdOrIds = array()) { $productIdOrIds = (array) $productIdOrIds; $productIdOrIds = array_filter(array_map('intval', $productIdOrIds)); return $this->getDi()->db->selectCell("SELECT MIN(begin_date) FROM ?_access WHERE user_id=?d AND begin_date > ? { AND product_id IN (?a) }", $this->pk(), sqlDate('now'), $productIdOrIds ? $productIdOrIds : DBSIMPLE_SKIP ); } function getRebill($productIdOrIds = array()) { $productIdOrIds = (array) $productIdOrIds; $productIdOrIds = array_filter(array_map('intval', $productIdOrIds)); return $this->getDi()->db->selectCell("SELECT MIN(i.rebill_date) FROM ?_access a LEFT JOIN ?_invoice_item ii ON a.invoice_id = ii.invoice_id AND a.product_id = ii.item_id AND ii.item_type = 'product' LEFT JOIN ?_invoice i ON a.invoice_id = i.invoice_id WHERE a.user_id=?d AND i.rebill_date IS NOT NULL AND i.status = ? AND i.rebill_date > ? AND ii.second_total > 0 {AND a.product_id IN (?a)}", $this->pk(), Invoice::RECURRING_ACTIVE, sqlDate('now'), $productIdOrIds ? $productIdOrIds : DBSIMPLE_SKIP ); } function getActiveProductsExpiration() { $ret = array(); foreach ($this->getActiveProductIds() as $pid) { $ret[$pid] = $this->getExpire($pid); } return $ret; } function getActiveCategoriesExpiration() { $p_map = $this->getActiveProductsExpiration(); $cp_map = $this->getDi()->productCategoryTable->getCategoryProducts(); $out = array_combine(array_keys($cp_map), array_fill(0, count($cp_map), null)); foreach ($cp_map as $cip => $pids) { foreach ($pids as $pid) { if (isset($p_map[$pid])) { $out[$cip] = max($out[$cip], $p_map[$pid]); } } } return array_filter($out); } function getFutureProductsBeginning() { $ret = array(); foreach ($this->getFutureProductIds() as $pid) { $ret[$pid] = $this->getBegin($pid); } return $ret; } function getActiveProductsRebill() { $ret = array(); foreach ($this->getActiveProductIds() as $pid) { $ret[$pid] = $this->getRebill($pid); } return $ret; } /** @return array of int active product# */ function getActiveProductIds() { return $this->getAdapter()->selectCol("SELECT product_id FROM ?_user_status WHERE user_id=?d AND status=?d", $this->user_id, self::STATUS_ACTIVE); } /** @return array of int expired product# */ function getExpiredProductIds() { return $this->getAdapter()->selectCol("SELECT product_id FROM ?_user_status WHERE user_id=?d AND status=?d", $this->user_id, self::STATUS_EXPIRED); } /** @return array of int future product# */ function getFutureProductIds() { return $this->getAdapter()->selectCol("SELECT DISTINCT a.product_id FROM ?_access a LEFT JOIN ?_user_status us USING(user_id,product_id) WHERE a.user_id = ? AND a.begin_date>? AND (us.status IS NULL OR us.status<>?)", $this->user_id, sqlDate('now'), self::STATUS_ACTIVE); } /** * @return array product_id => status (@see self::STATUS_ACTIVE, ... constants) */ function getProductsStatus() { return $this->getDi()->userStatusTable->getByUserId($this->user_id); } /// -- implementing IMailReceiver interface */ public function getEmail() { return $this->email; } public function getName() { return trim(@$this->name_f . ' ' . @$this->name_l); } public function isUnsubscribed() { return (bool) $this->unsubscribed; } public function canUnsubscribe() { return true; } /** param array $groups - array of id# */ function setGroups(array $groups) { $this->getAdapter()->query("DELETE FROM ?_user_user_group WHERE user_id=?d {AND user_group_id NOT IN (?a)}", $this->user_id, $groups ? $groups : DBSIMPLE_SKIP); if ($groups) { $vals = array(); foreach ($groups as $id) $vals[] = sprintf("(%d,%d)", $this->user_id, $id); $this->getAdapter()->query("INSERT IGNORE INTO ?_user_user_group (user_id, user_group_id) VALUES " . implode(", ", $vals)); } $this->checkSubscriptions(true); return $this; } /** @return array of id# */ function getGroups() { if (empty($this->user_id)) return array(); return $this->getAdapter()->selectCol( "SELECT DISTINCT user_group_id FROM ?_user_user_group WHERE user_id=?d", $this->user_id); } } /** * @method findFirstByLogin($login) * @method findFirstByEmail($login) */ class UserTable extends Am_Table_WithData { protected $_key = 'user_id'; protected $_table = '?_user'; protected $_recordClass = 'User'; protected $sort_order = array(); protected $_customFieldsConfigKey = 'member_fields'; public function clearPending($date, $incl_aff = false) { $q = $this->_db->queryResultOnly("SELECT u.* FROM ?_user u LEFT JOIN ?_access a ON a.user_id = u.user_id LEFT JOIN ?_invoice_payment ip ON ip.user_id = u.user_id WHERE u.status = 0 {AND IFNULL(u.is_affiliate,0)=?} AND a.access_id IS NULL AND ip.invoice_payment_id is NULL AND u.added < ? GROUP BY u.user_id", ($incl_aff ? DBSIMPLE_SKIP : 0), sqlTime($date)); while ($r = $this->_db->fetchRow($q)) { $u = $this->createRecord($r); $u->delete(); } } public function clearExpired($date, $incl_aff = false) { // this function deletes only 500 records at time, to do not work over limits $q = $this->_db->queryResultOnly("SELECT u.* FROM ?_user u LEFT JOIN ?_access a ON a.user_id = u.user_id LEFT JOIN ?_invoice_payment ip ON ip.user_id = u.user_id WHERE u.status = 2 {AND IFNULL(u.is_affiliate,0)=?} GROUP BY u.user_id HAVING GREATEST( IFNULL(MAX(ip.dattm), '2000-01-01'), IFNULL(MAX(a.expire_date), '2000-01-01')) < ? LIMIT 500 ", ($incl_aff ? DBSIMPLE_SKIP : 0), sqlTime($date)); while ($r = $this->_db->fetchRow($q)) { $u = $this->createRecord($r); $u->delete(); } } function getLoginRegex() { $regexp = $this->getDi()->config->get('login_disallow_spaces') ? '/^[-0-9a-zA-Z_]+$/D' : '/^([-0-9a-zA-Z_][-0-9a-zA-Z_ ]+[-0-9a-zA-Z_]|[-0-9a-zA-Z_]+)$/D'; $event = new Am_Event(Am_Event::GET_LOGIN_REGEX, array( 'login_disallow_spaces' => $this->getDi()->config->get('login_disallow_spaces') )); $event->setReturn($regexp); $this->getDi()->hook->call($event); return $event->getReturn(); } function getStrongPasswordRegex() { $regexp = '/^(?=.*[0-9].*[0-9])(?=.*[-!@#$%^&*().,=+`~{}\?].*[-!@#$%^&*().,=+`~{}\?])(?=.*[A-Z].*[A-Z])/'; $event = new Am_Event(Am_Event::GET_STRONG_PASSWORD_REGEX); $event->setReturn($regexp); $this->getDi()->hook->call($event); return $event->getReturn(); } /** * Check for username iniqueness only * @param string $login * @return bool True if record unique (no such login exists), false if not-unique */ function checkUniqLogin($login, $user_id = null) { $u = $this->_db->selectCell("SELECT user_id FROM ?_user WHERE login=? { AND user_id <> ?d}", $login, $user_id ? $user_id : DBSIMPLE_SKIP); if ($u) return 0; $event = $this->getDi()->hook->call(new Am_Event_CheckUniqLogin(null, array('login' => $login, 'userId' => $user_id))); return $event->isUnique() ? -1 : false; } /** * Check for username iniqueness only * @param string $login * @return bool True if record unique (no such login exists), false if not-unique */ function checkUniqEmail($email, $user_id = null) { $u = $this->_db->selectCell("SELECT user_id FROM ?_user WHERE email=? { AND user_id <> ?d}", $email, $user_id ? $user_id : DBSIMPLE_SKIP); if ($u) return 0; $event = $this->getDi()->hook->call(new Am_Event_CheckUniqEmail(null, array('email' => $email, 'userId' => $user_id))); return $event->isUnique() ? -1 : false; } function checkAllSubscriptionsFindChanged($limit = null) { $db = $this->_db; // update resource_access_cache $this->getDi()->resourceAccessTable->updateCache(); $db->query("DELETE FROM ?_user_status WHERE user_id NOT IN (SELECT user_id FROM ?_user)"); $db->query("DELETE FROM ?_access WHERE user_id NOT IN (SELECT user_id FROM ?_user)"); $db->query("DROP TABLE IF EXISTS ?_user_status_temp"); $db->query("CREATE TEMPORARY TABLE ?_user_status_temp ( user_id int not null, product_id int not null, status tinyint not null, INDEX(user_id,product_id)) "); // create table with calculated records from "access" $db->query(" INSERT INTO ?_user_status_temp SELECT a.user_id,a.product_id, CASE WHEN SUM(IF(a.expire_date>=?, 1, 0)) THEN 1 WHEN SUM(IF(a.expire_date< ?, 1, 0)) THEN 2 ELSE 0 END as status FROM ?_access a WHERE a.begin_date<=? GROUP BY user_id,product_id ", $this->getDi()->sqlDate, $this->getDi()->sqlDate, $this->getDi()->sqlDate); // now select differences $ids0 = $db->selectCol(" SELECT DISTINCT ms.user_id FROM ?_user_status ms LEFT JOIN ?_user_status_temp mst ON ms.user_id =mst.user_id AND ms.product_id=mst.product_id AND ms.status =mst.status WHERE mst.user_id IS NULL GROUP BY ms.user_id,ms.product_id {LIMIT ?d}", is_null($limit) ? DBSIMPLE_SKIP : $limit); if (!is_null($limit)) $limit = $limit - count($ids0); // select if there is no such a record in user_status table $ids1 = $db->selectCol("SELECT DISTINCT mst.user_id FROM ?_user_status_temp mst LEFT JOIN ?_user_status ms ON ms.user_id =mst.user_id AND ms.product_id=mst.product_id AND ms.status =mst.status WHERE ms.user_id IS NULL GROUP BY mst.user_id,mst.product_id {LIMIT ?d}", is_null($limit) ? DBSIMPLE_SKIP : $limit); if (!is_null($limit)) $limit = $limit - count($ids1); // select if user record has different "status" value $ids2 = $db->selectCol("SELECT DISTINCT m.user_id, CASE WHEN SUM(IF(mst.status=1, 1, 0)) THEN 1 WHEN SUM(IF(mst.status=2, 1, 0)) THEN 2 ELSE 0 END AS calcStatus, m.status FROM ?_user m LEFT JOIN ?_user_status_temp mst USING (user_id) GROUP BY m.user_id HAVING IFNULL(calcStatus,0) <> IFNULL(m.status, 0) {LIMIT ?d}", is_null($limit) ? DBSIMPLE_SKIP : $limit); return array_unique(array_merge($ids0, $ids1, $ids2)); } /** * If this function changed, check also AdminRebuildController - it must be changed too */ function checkAllSubscriptions() { while ($changed = $this->checkAllSubscriptionsFindChanged(1000)) { foreach ($changed as $user_id) { $u = $this->load($user_id, false); if ($u) $u->checkSubscriptions(false); // checked in checkAllSubscriptionsFindChanged } } } /** * Find user record by email (if $login looks like an email) * or by username * @param string $login e-mail or username * @return User|null */ function getByLoginOrEmail($login) { if (!strlen($login)) return null; if (strpos($login, '@') !== false) return $this->findFirstByEmail($login); else return $this->findFirstByLogin($login); } /** * Find record by login, check password and return it if all OK * with login/password * sets $resultCode from Am_Auth_Result * @return User */ function getAuthenticatedRow($login, $pass, & $code = null) { if (empty($login) || empty($pass)) { $code = Am_Auth_Result::INVALID_INPUT; return; } $u = $this->getByLoginOrEmail($login); if (!$u) { $code = Am_Auth_Result::USER_NOT_FOUND; return; } if (!$u->checkPassword($pass)) { $code = Am_Auth_Result::WRONG_CREDENTIALS; return; } $code = Am_Auth_Result::SUCCESS; return $u; } function getAuthenticatedCookieRow($cLogin, $cPass, & $code = null) { if (empty($cLogin) || empty($cPass)) { $code = Am_Auth_Result::INVALID_INPUT; return null; } $u = $this->getByLoginOrEmail($cLogin); if (!$u) { $code = Am_Auth_Result::USER_NOT_FOUND; return; } if ($u->getLoginCookie() !== $cPass) { $code = Am_Auth_Result::WRONG_CREDENTIALS; return null; } $code = Am_Auth_Result::SUCCESS; return $u; } function selectLast($num, $dateThreshold = null) { return $this->selectObjects("SELECT m.*, ROUND(SUM((p.amount - IFNULL(p.refund_amount, 0))/p.base_currency_multi), 2) AS paid, COUNT(p.invoice_payment_id) AS payments_count, sf.title AS saved_form_title FROM ?_user m LEFT JOIN ?_invoice_payment p USING (user_id) LEFT JOIN ?_saved_form sf ON m.saved_form_id=sf.saved_form_id {WHERE added > ?} GROUP BY m.user_id ORDER BY m.user_id DESC LIMIT ?d", $dateThreshold ?: DBSIMPLE_SKIP, $num); } }home/ajdemo/public_html/mempro/library/Am/Auth/User.php000064400000017031152101641450017066 0ustar00getUserId()) { $front = $this->getDi()->front; if (!$front->getRequest()) $front->setRequest(new Am_Mvc_Request); else $front->setRequest(clone $front->getRequest()); $front->getRequest()->setActionName('index'); if (!$front->getResponse()) $front->setResponse(new Am_Mvc_Response); require_once AM_APPLICATION_PATH . '/default/controllers/LoginController.php'; $c = new LoginController( $front->getRequest(), $front->getResponse(), array('di' => Am_Di::getInstance())); if ($redirectUrl) $c->setRedirectUrl($redirectUrl); $c->run(); $front->getResponse()->sendResponse(); exit(); }else { $this->getDi()->accessLogTable->logOnce($this->getUserId()); } } /** * Once the customer is logged in, check if he has access to given products (links) * @throws Am_Exception_InputError if access not allowed */ public function checkAccess($productIds, $linkIds=null) { if (!array_intersect($productIds, $this->getUser()->getActiveProductIds())) throw new Am_Exception_AccessDenied(___('You have no subscription')); } public function refreshUserSession(Am_Event $e) { if ($user = $this->getUser()) { $user->data()->set(User::NEED_SESSION_REFRESH, false)->update(); $this->getDi()->hook->call(new Am_Event_AuthSessionRefresh($user)); } } public function checkExternalLogin(Am_Mvc_Request $request) { $adapters = array(); if ($this->getDi()->config->get('protect.php_include.remember_login', false)) { $adapters[] = new Am_Auth_Adapter_Cookie( $request->getCookie('amember_ru'), $request->getCookie('amember_rp'), $this->getDi()->userTable); } $adapters[] = new Am_Auth_Adapter_Plugin($this->getDi()->hook); foreach ($adapters as $adapter) { $res = $this->login($adapter, $request->getClientIp()); if ($res->isValid()) return true; } return false; } public function logout() { if ($u = $this->getUser()) { $u->updateQuick('remember_key', sha1(rand())); $this->getDi()->hook->call( new Am_Event_AuthAfterLogout($this->getUser())); } return parent::logout(); } /** run additional checks on authenticated user */ public function checkUser($user, $ip = null) { /* @var $user User */ if (!$user->isLocked()) { if (!is_null($ip)) { // now log access and check for account sharing $accessLog = $this->getDi()->accessLogTable; $accessLog->logOnce($user->user_id, $ip); if (($user->is_locked >=0) && $user->disable_lock_until < $this->getDi()->sqlDateTime && $accessLog->isIpCountExceeded($user->user_id, $ip)) { $this->onIpCountExceeded($user); $this->setUser(null, null); return new Am_Auth_Result(Am_Auth_Result::LOCKED); } } } else { $this->setUser(null, null); return new Am_Auth_Result(Am_Auth_Result::LOCKED); } if (!$user->isApproved()) return new Am_Auth_Result(Am_Auth_Result::NOT_APPROVED); $event = new Am_Event(Am_Event::AUTH_CHECK_USER, array('user' => $user, 'ip' => $ip)); $event->setReturn(null); $this->getDi()->hook->call($event); return $event->getReturn(); } protected function onSuccess() { $user = $this->getUser(); if ($user && $user->last_session != Zend_Session::getId()) { $ip = $this->getDi()->request->getClientIp(); $user->last_ip = filter_var($ip, FILTER_VALIDATE_IP); $user->last_user_agent = @$_SERVER['HTTP_USER_AGENT']; $user->last_login = $this->getDi()->sqlDateTime; $user->last_session = Zend_Session::getId(); $user->updateSelectedFields(array('last_ip', 'last_user_agent', 'last_login', 'last_session')); } $this->getDi()->hook->call( new Am_Event_AuthAfterLogin($this->getUser(), $this->plaintextPass)); } protected function onIpCountExceeded(User $user) { if ($user->is_locked < 0) return; // auto-lock disabled if ($this->getDi()->store->get('on-ip-count-exceeded-' . $user->pk())) return; //action already done $this->getDi()->store->set('on-ip-count-exceeded-' . $user->pk(), 1, '+20 minutes'); if (in_array('email-admin', $this->getDi()->config->get('max_ip_actions', array()))) { $et = Am_Mail_Template::load('max_ip_actions_admin'); if (!$et) throw new Am_Exception_Configuration("No e-mail template found for [max_ip_actions_admin]"); $et->setMaxipcount($this->getDi()->config->get('max_ip_count', 0)) ->setMaxipperiod($this->getDi()->config->get('max_ip_period', 0)) ->setUser($user); $et->setUserlocked(''); if (in_array('disable-user', $this->getDi()->config->get('max_ip_actions', array()))) $et->setUserlocked(___('Customer account has been automatically locked.')); $et->sendAdmin(); } if (in_array('email-user', $this->getDi()->config->get('max_ip_actions', array()))) { $et = Am_Mail_Template::load('max_ip_actions_user'); if (!$et) throw new Am_Exception_Configuration("No e-mail template found for [max_ip_actions_user]"); $et->setMaxipcount($this->getDi()->config->get('max_ip_count', 0)) ->setMaxipperiod($this->getDi()->config->get('max_ip_period', 0)) ->setUser($user); $et->setUserlocked(''); if (in_array('disable-user', $this->getDi()->config->get('max_ip_actions', array()))) $et->setUserlocked(___('Your account has been automatically locked.')); $et->send($user->email); } if (in_array('disable-user', $this->getDi()->config->get('max_ip_actions', array()))) { // disable customer $user->lock(); } } static function _setInstance($instance) { self::$instance = $instance; } protected function loadUser() { $var = $this->getSessionVar(); $id = $var[$this->idField]; if ($id < 0) throw new Am_Exception_InternalError('Empty id'); $user = $this->getDi()->userTable->load($id, false); if ($user && $user->data()->get(User::NEED_SESSION_REFRESH)) { $this->getDi()->hook->add(Am_Event::INIT_FINISHED, array($this, 'refreshUserSession')); } if ($id && is_null($user)) { /* * User was not loaded - something is wrong. * We need to clean session; */ $this->setSessionVar(null); } return $user; } }home/ajdemo/public_html/mempro/library/Am/Auth/Adapter/User.php000064400000000465152101701170020445 0ustar00user = $user; } public function authenticate() { return new Am_Auth_Result(Am_Auth_Result::SUCCESS, null, $this->user); } }