Users.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. <?php
  2. /**
  3. *
  4. * PHP Pro Bid $Id$ Nz3Tz2sMs25Q1mXlp28//dTe1bcmWSgKR2rKzMPhtCI=
  5. *
  6. * @link http://www.phpprobid.com
  7. * @copyright Copyright (c) 2016 Online Ventures Software & CodeCube SRL
  8. * @license http://www.phpprobid.com/license Commercial License
  9. *
  10. * @version 7.7
  11. */
  12. /**
  13. * users table service class
  14. */
  15. namespace Ppb\Service;
  16. use Ppb\Db\Table\Users as UsersTable,
  17. Ppb\Service,
  18. Ppb\Model\Shipping as ShippingModel,
  19. Ppb\Db\Table\Row\User as UserModel,
  20. Cube\Db\Expr;
  21. class Users extends AbstractService
  22. {
  23. /**
  24. * admin user roles
  25. */
  26. const ADMIN_ROLE_PRIMARY = 'Admin';
  27. const ADMIN_ROLE_MANAGER = 'Manager';
  28. protected static $_adminRoles = array(
  29. self::ADMIN_ROLE_PRIMARY => 'Administrator',
  30. self::ADMIN_ROLE_MANAGER => 'Manager',
  31. );
  32. /**
  33. * custom fields tables "type" column
  34. */
  35. const CUSTOM_FIELDS_TYPE = 'user';
  36. /**
  37. *
  38. * custom fields data table service
  39. *
  40. * @var \Ppb\Service\CustomFieldsData
  41. */
  42. protected $_customFieldsData;
  43. /**
  44. *
  45. * payment gateways service
  46. *
  47. * @var \Ppb\Service\Table\PaymentGateways
  48. */
  49. protected $_paymentGateways;
  50. /**
  51. *
  52. * users address book table service
  53. *
  54. * @var \Ppb\Service\UsersAddressBook
  55. */
  56. protected $_usersAddressBook;
  57. /**
  58. *
  59. * user subscriptions that are used when:
  60. * - disabling expired subscriptions,
  61. * - re-billing automatically in account mode
  62. * - notifying users by email that subscriptions are about to expire
  63. *
  64. * @var array
  65. */
  66. protected $_subscriptionTypes = array(
  67. 'UserVerification' => array(
  68. 'name' => 'User Verification Subscription',
  69. 'active' => 'user_verified',
  70. 'expirationDate' => 'user_verified_next_payment',
  71. 'emailFlag' => 'user_verified_email',
  72. 'updateMethod' => 'updateUserVerification',
  73. 'feesService' => '\Ppb\Service\Fees\UserVerification',
  74. 'renewalLink' => array('module' => 'app', 'controller' => 'payment', 'action' => 'user-verification'),
  75. 'managementLink' => array('module' => 'members', 'controller' => 'user', 'action' => 'verification'),
  76. ),
  77. 'StoreSubscription' => array(
  78. 'name' => 'Store Subscription',
  79. 'active' => 'store_active',
  80. 'expirationDate' => 'store_next_payment',
  81. 'emailFlag' => 'store_expiration_email',
  82. 'updateMethod' => 'updateStoreSubscription',
  83. 'feesService' => '\Ppb\Service\Fees\StoreSubscription',
  84. 'renewalLink' => array('module' => 'app', 'controller' => 'payment', 'action' => 'store-subscription'),
  85. 'managementLink' => array('module' => 'members', 'controller' => 'store', 'action' => 'setup'),
  86. ),
  87. );
  88. /**
  89. *
  90. * class constructor
  91. */
  92. public function __construct()
  93. {
  94. parent::__construct();
  95. $this->setTable(
  96. new UsersTable());
  97. }
  98. /**
  99. *
  100. * set custom fields data service
  101. *
  102. * @param \Ppb\Service\CustomFieldsData $customFieldsData
  103. *
  104. * @return \Ppb\Service\Users
  105. */
  106. public function setCustomFieldsDataService(Service\CustomFieldsData $customFieldsData)
  107. {
  108. $this->_customFieldsData = $customFieldsData;
  109. return $this;
  110. }
  111. /**
  112. *
  113. * get custom fields data service
  114. *
  115. * @return \Ppb\Service\CustomFieldsData
  116. */
  117. public function getCustomFieldsDataService()
  118. {
  119. if (!$this->_customFieldsData instanceof Service\CustomFieldsData) {
  120. $this->setCustomFieldsDataService(
  121. new Service\CustomFieldsData());
  122. }
  123. return $this->_customFieldsData;
  124. }
  125. /**
  126. *
  127. * set payment gateways service
  128. *
  129. * @param \Ppb\Service\Table\PaymentGateways $paymentGateways
  130. *
  131. * @return \Ppb\Service\Users
  132. */
  133. public function setPaymentGateways(Service\Table\PaymentGateways $paymentGateways)
  134. {
  135. $this->_paymentGateways = $paymentGateways;
  136. return $this;
  137. }
  138. /**
  139. *
  140. * get payment gateways service
  141. *
  142. * @return \Ppb\Service\Table\PaymentGateways
  143. */
  144. public function getPaymentGateways()
  145. {
  146. if (!$this->_paymentGateways instanceof Service\Table\PaymentGateways) {
  147. $this->setPaymentGateways(
  148. new Service\Table\PaymentGateways());
  149. }
  150. return $this->_paymentGateways;
  151. }
  152. /**
  153. *
  154. * set users address book service
  155. *
  156. * @param \Ppb\Service\UsersAddressBook $addressBook
  157. *
  158. * @return \Ppb\Service\Users
  159. */
  160. public function setUsersAddressBook(Service\UsersAddressBook $addressBook)
  161. {
  162. $this->_usersAddressBook = $addressBook;
  163. return $this;
  164. }
  165. /**
  166. *
  167. * get users address book service
  168. *
  169. * @return \Ppb\Service\UsersAddressBook
  170. */
  171. public function getUsersAddressBook()
  172. {
  173. if (!$this->_usersAddressBook instanceof Service\UsersAddressBook) {
  174. $this->setUsersAddressBook(
  175. new Service\UsersAddressBook());
  176. }
  177. return $this->_usersAddressBook;
  178. }
  179. /**
  180. *
  181. * set subscription types array
  182. *
  183. * @param array $subscriptionTypes
  184. *
  185. * @return $this
  186. */
  187. public function setSubscriptionTypes($subscriptionTypes)
  188. {
  189. $this->_subscriptionTypes = $subscriptionTypes;
  190. return $this;
  191. }
  192. /**
  193. *
  194. * get subscription types array
  195. *
  196. * @return array
  197. */
  198. public function getSubscriptionTypes()
  199. {
  200. return $this->_subscriptionTypes;
  201. }
  202. /**
  203. *
  204. * set admin roles
  205. *
  206. * @param $adminRoles
  207. */
  208. public static function setAdminRoles($adminRoles)
  209. {
  210. self::$_adminRoles = $adminRoles;
  211. }
  212. /**
  213. *
  214. * get admin roles
  215. *
  216. * @return array
  217. */
  218. public static function getAdminRoles()
  219. {
  220. return self::$_adminRoles;
  221. }
  222. /**
  223. *
  224. * find a row on the table by querying a certain column
  225. * also get the primary address from the UsersAddressBook table
  226. *
  227. * @param string $name column name
  228. * @param string $value column value
  229. * @param bool $enhanced if set to true, it will retrieve all additional related data as an array (including the primary address)
  230. *
  231. * @return \Ppb\Db\Table\Row\User
  232. */
  233. public function findBy($name, $value, $enhanced = false)
  234. {
  235. /** @var \Ppb\Db\Table\Row\User $user */
  236. $user = parent::findBy($name, $value);
  237. if (count($user) > 0) {
  238. $user->setAddress();
  239. if ($enhanced === true) {
  240. // custom fields data
  241. $customFieldsData = $this->getCustomFieldsData($user['id']);
  242. foreach ($customFieldsData as $key => $value) {
  243. $user['custom_field_' . $key] = $value;
  244. }
  245. }
  246. }
  247. return $user;
  248. }
  249. /**
  250. *
  251. * save users data in the users table
  252. * also create the postage settings default array (type = item and shipping locations = domestic)
  253. *
  254. * @param array $post
  255. * @param int $userId used for when editing a user
  256. *
  257. * @return int the id of the user that was saved
  258. */
  259. public function save($post, $userId = null)
  260. {
  261. $user = null;
  262. $data = $this->_prepareSaveData($post);
  263. if ($userId !== null) {
  264. $user = $this->findBy('id', $userId);
  265. }
  266. else if (array_key_exists('username', $post)) {
  267. $user = $this->findBy('username', $post['username']);
  268. }
  269. if (isset($post['name'])) {
  270. $post['first_name'] = (!empty($post['name']['first'])) ? $post['name']['first'] : '';
  271. $post['last_name'] = (!empty($post['name']['last'])) ? $post['name']['last'] : '';
  272. }
  273. if (count($user) > 0) {
  274. $data['updated_at'] = new Expr('now()');
  275. unset($data['username']);
  276. $this->_table->update($data, "id='{$user['id']}'");
  277. $id = $user['id'];
  278. }
  279. else {
  280. $data['created_at'] = new Expr('now()');
  281. if (!isset($data['postage_settings'])) {
  282. $data['postage_settings'] = serialize(array(
  283. ShippingModel::SETUP_SHIPPING_LOCATIONS => ShippingModel::POSTAGE_LOCATION_DOMESTIC,
  284. ShippingModel::SETUP_POSTAGE_TYPE => ShippingModel::POSTAGE_TYPE_ITEM,
  285. ShippingModel::SETUP_FREE_POSTAGE => 0,
  286. ));
  287. }
  288. $settings = $this->getSettings();
  289. $data['balance'] = (-1) * $settings['signup_credit'];
  290. $data['max_debit'] = doubleval($settings['maximum_debit']);
  291. $data['account_mode'] = $settings['payment_mode'];
  292. $this->_table->insert($data);
  293. $id = $this->_table->getAdapter()->lastInsertId();
  294. $user = $this->findBy('id', $id);
  295. }
  296. if (!empty($post['password'])) {
  297. $this->savePassword($user, $post['password']);
  298. }
  299. if (!isset($post['partial'])) {
  300. // save custom fields data in the database
  301. foreach ($post as $key => $value) {
  302. if (strstr($key, 'custom_field_')) {
  303. $fieldId = str_replace('custom_field_', '', $key);
  304. $this->getCustomFieldsDataService()->save(
  305. $value, self::CUSTOM_FIELDS_TYPE, $fieldId, $id);
  306. }
  307. }
  308. // save payment gateways data in the database
  309. $gatewayFields = $this->getPaymentGateways()->getDirectPaymentFields();
  310. foreach ($gatewayFields as $key => $gatewayField) {
  311. $gatewayFields[$key]['user_id'] = $id;
  312. if (array_key_exists($gatewayField['name'], $post)) {
  313. $gatewayFields[$key]['value'] = $post[$gatewayField['name']];
  314. }
  315. }
  316. foreach ((array)$gatewayFields as $gatewayField) {
  317. $this->getPaymentGateways()->getPaymentGatewaysSettings()->save($gatewayField);
  318. }
  319. // save the user's address in the address book (but only if the address form - at least one field from it - is present)
  320. if (array_intersect($this->getUsersAddressBook()->getAddressFields(), array_keys($post))) {
  321. $this->getUsersAddressBook()->save($post, $id);
  322. }
  323. }
  324. return $id;
  325. }
  326. /**
  327. *
  328. * hash a password
  329. *
  330. * @param string $password
  331. * @param string $salt
  332. *
  333. * @return string hashed password
  334. */
  335. public function hashPassword($password, $salt)
  336. {
  337. return hash('sha256', $password . $salt);
  338. }
  339. /**
  340. *
  341. * save a password for a certain user in the users table
  342. *
  343. * @param \Ppb\Db\Table\Row\User $user
  344. * @param string $password the raw password
  345. *
  346. * @return $this
  347. */
  348. public function savePassword(UserModel $user, $password)
  349. {
  350. $salt = date('U', time());
  351. $password = $this->hashPassword($password, $salt);
  352. $user->save(array(
  353. 'password' => $password,
  354. 'salt' => $salt,
  355. ));
  356. return $this;
  357. }
  358. /**
  359. *
  360. * delete a user from the table
  361. *
  362. * @param integer $userId the id of the user
  363. *
  364. * @return integer the number of affected rows
  365. */
  366. public function delete($userId)
  367. {
  368. $where = $this->_table->getAdapter()->quoteInto('id = ?', $userId);
  369. return $this->_table->delete($where);
  370. }
  371. /**
  372. *
  373. * generate a unique registration key used for verifying the user's email address
  374. *
  375. * @param integer $id
  376. * @param string $username
  377. *
  378. * @return string
  379. */
  380. public function generateRegistrationKey($id, $username)
  381. {
  382. $hash = md5(uniqid(time()));
  383. return substr(
  384. hash('sha256', $id . $username . $hash), 0, 10);
  385. }
  386. /**
  387. *
  388. * verify an email address and return true if successful, false otherwise
  389. *
  390. * @param string $key the key used to verify the account
  391. *
  392. * @return bool
  393. */
  394. public function verifyEmailAddress($key)
  395. {
  396. return (bool)$this->_table->update(array('mail_activated' => 1), "registration_key='{$key}'");
  397. }
  398. /**
  399. *
  400. * unsubscribe user from newsletter
  401. *
  402. * @param string $username
  403. * @param string $email
  404. *
  405. * @return bool
  406. */
  407. public function newsletterUnsubscribe($username, $email)
  408. {
  409. return (bool)$this->_table->update(array('newsletter_subscription' => 0), "username='{$username}' AND email='{$email}'");
  410. }
  411. /**
  412. *
  413. * get the custom fields data of a certain user
  414. *
  415. * @param integer $id
  416. *
  417. * @return array
  418. */
  419. public function getCustomFieldsData($id)
  420. {
  421. $result = array();
  422. // custom fields data
  423. $rowset = $this->getCustomFieldsDataService()->fetchAll(
  424. $this->getCustomFieldsDataService()->getTable()->select('value, field_id')
  425. ->where('type = ?', self::CUSTOM_FIELDS_TYPE)
  426. ->where('owner_id = ?', (int)$id));
  427. foreach ($rowset as $row) {
  428. $result[$row['field_id']] = \Ppb\Utility::unserialize($row['value']);
  429. }
  430. return $result;
  431. }
  432. /**
  433. *
  434. * prepare user data for when saving to the table
  435. *
  436. * @param array $data
  437. *
  438. * @return array
  439. */
  440. protected function _prepareSaveData($data = array())
  441. {
  442. if (isset($data['id'])) {
  443. unset($data['id']);
  444. }
  445. if (isset($data['password'])) {
  446. unset($data['password']);
  447. }
  448. if (isset($data['salt'])) {
  449. unset($data['salt']);
  450. }
  451. return parent::_prepareSaveData($data);
  452. }
  453. }