/**
  * Increase one sms to the subscription with given mobile
  *
  * @param string $mobile
  *
  * @throws NonExistentMobileInternalException
  */
 public function increase($mobile)
 {
     $result = $this->connectToStorageInternalWorker->connect()->update(array('mobile' => $mobile), array('$inc' => array('balance' => 1)));
     if ($result['n'] == 0) {
         throw new NonExistentMobileInternalException($mobile);
     }
 }
 /**
  * Collects subscriptions by given topics.
  *
  * @param string[] $topics
  *
  * @return \Iterator An array of subscriptions with the following keys:
  *                   mobile, uniqueness, alias, topics, balance and active
  */
 public function collect($topics)
 {
     $query = [];
     foreach ($topics as $topic) {
         $query[] = ['topics' => $topic];
     }
     return $this->connectToStorageInternalWorker->connect()->find(['$or' => $query])->fields(['_id' => 0])->sort(['order' => -1]);
 }
 /**
  * Picks the subscription with given mobile and uniqueness.
  *
  * @param string $mobile
  * @param string $uniqueness
  *
  * @return array A subscription as an array with the following keys:
  *               mobile, uniqueness, alias, topics, balance and active
  *
  * @throws NonExistentMobileAndUniquenessApiException
  */
 public function pick($mobile, $uniqueness)
 {
     $subscription = $this->connectToStorageInternalWorker->connect()->findOne(['mobile' => $mobile, 'uniqueness' => $uniqueness], ['_id' => 0, 'order' => 0]);
     if (!$subscription) {
         throw new NonExistentMobileAndUniquenessApiException();
     }
     return $subscription;
 }
 /**
  * @param string   $mobile
  * @param string   $uniqueness
  * @param string   $alias
  * @param string[] $topics
  * @param int      $trial
  * @param int      $balance
  * @param boolean  $active
  *
  * @throws ExistentMobileInternalException
  * @throws \MongoCursorException
  */
 public function create($mobile, $uniqueness, $alias, $topics, $trial, $balance, $active)
 {
     try {
         $this->connectToStorageInternalWorker->connect()->insert(['mobile' => $mobile, 'uniqueness' => $uniqueness, 'alias' => $alias, 'topics' => $topics, 'trial' => $trial, 'balance' => $balance, 'active' => $active]);
     } catch (\MongoCursorException $e) {
         if (11000 == $e->getCode()) {
             throw new ExistentMobileInternalException();
         }
         throw $e;
     }
 }
 /**
  * Deletes the subscription with given mobile and uniqueness.
  *
  * @param string $mobile
  * @param string $uniqueness
  *
  * @throws NonExistentMobileAndUniquenessApiException
  */
 public function delete($mobile, $uniqueness)
 {
     $subscription = $this->connectToStorageInternalWorker->connect()->findOne(['mobile' => $mobile, 'uniqueness' => $uniqueness]);
     if (!$subscription) {
         throw new NonExistentMobileAndUniquenessApiException();
     }
     // Increase to the balance what the subscription balance has
     $this->increaseBalanceInternalWorker->increase($uniqueness, $subscription['balance']);
     // Remove subscription
     $this->connectToStorageInternalWorker->connect()->remove(['mobile' => $mobile, 'uniqueness' => $uniqueness]);
     $this->logOperationInternalWorker->logDelete($mobile, $uniqueness, $subscription['topics'], $subscription['trial'], $subscription['balance'], time());
 }
 /**
  * Validates given mobile and alias.
  *
  * @param string $mobile
  * @param string $alias
  *
  * @throws InvalidMobileInternalException
  * @throws BlankAliasInternalException
  * @throws ExistentMobileInternalException
  */
 public function validate($mobile, $alias)
 {
     try {
         PhoneNumberFixer::fix($mobile);
     } catch (\InvalidArgumentException $e) {
         throw new InvalidMobileInternalException();
     }
     if ($alias === '') {
         throw new BlankAliasInternalException();
     }
     $subscription = $this->connectToStorageInternalWorker->connect()->findOne(['mobile' => $mobile]);
     if ($subscription) {
         throw new ExistentMobileInternalException();
     }
 }
 /**
  * Decreases one sms to the subscription with given mobile.
  *
  * @param string $mobile
  *
  * @throws NonExistentMobileInternalException
  * @throws InactiveInternalException
  * @throws InsufficientBalanceInternalException
  */
 public function decrease($mobile)
 {
     $item = $this->connectToStorageInternalWorker->connect()->findOne(['mobile' => $mobile]);
     if (!$item) {
         throw new NonExistentMobileInternalException($mobile);
     }
     if ($item['active'] == false) {
         throw new InactiveInternalException();
     }
     if ($item['trial'] > 0) {
         $this->connectToStorageInternalWorker->connect()->update(array('mobile' => $mobile), array('$inc' => array('trial' => -1)));
     } elseif ($item['balance'] > 0) {
         $this->connectToStorageInternalWorker->connect()->update(array('mobile' => $mobile), array('$inc' => array('balance' => -1)));
     } else {
         throw new InsufficientBalanceInternalException();
     }
 }
 /**
  * Updates the subscription with given mobile and uniqueness.
  *
  * @param string   $mobile
  * @param string   $uniqueness
  * @param string   $alias
  * @param string[] $topics
  * @param boolean  $active
  *
  * @throws BlankAliasApiException
  * @throws NoTopicsApiException
  * @throws NonExistentIdApiException
  * @throws NonExistentMobileAndUniquenessApiException
  */
 public function update($mobile, $uniqueness, $alias, $topics, $active)
 {
     if ($alias === '') {
         throw new BlankAliasApiException();
     }
     if (count($topics) == 0) {
         throw new NoTopicsApiException();
     }
     foreach ($topics as $topic) {
         try {
             $this->pickTopicApiWorker->pick($topic);
         } catch (NonExistentIdApiException $e) {
             throw $e;
         }
     }
     $result = $this->connectToStorageInternalWorker->connect()->update(['mobile' => $mobile, 'uniqueness' => $uniqueness], ['$set' => ['alias' => $alias, 'topics' => $topics, 'active' => $active, 'order' => time()]]);
     if ($result['n'] == 0) {
         throw new NonExistentMobileAndUniquenessApiException();
     }
 }
 /**
  * @param string   $mobile
  * @param string   $uniqueness
  * @param string[] $topics
  * @param string   $resellPackage
  *
  * @throws NonExistentMobileAndUniquenessApiException
  * @throws NoTopicsApiException
  * @throws NonExistentTopicApiException
  * @throws NoResellPackageApiException
  * @throws NonExistentResellPackageInternalException
  * @throws TrialNotAcceptedApiException
  * @throws InsufficientBalanceApiException
  */
 public function recharge($mobile, $uniqueness, $topics, $resellPackage)
 {
     $subscription = $this->connectToStorageInternalWorker->connect()->findOne(['mobile' => $mobile, 'uniqueness' => $uniqueness]);
     if (!$subscription) {
         throw new NonExistentMobileAndUniquenessApiException();
     }
     if (count($topics) == 0) {
         throw new NoTopicsApiException();
     }
     foreach ($topics as $topic) {
         try {
             $this->pickTopicApiWorker->pick($topic);
         } catch (NonExistentIdApiException $e) {
             throw new NonExistentTopicApiException();
         }
     }
     if (!$resellPackage) {
         throw new NoResellPackageApiException();
     }
     // Pick resell package to use amount
     try {
         $resellPackage = $this->pickResellPackageInternalWorker->pick($resellPackage);
     } catch (NonExistentResellPackageInternalException $e) {
         throw $e;
     }
     if ($resellPackage['price'] == 0) {
         throw new TrialNotAcceptedApiException();
     }
     if (!$this->checkBalanceInternalWorker->check($uniqueness, $resellPackage['amount'])) {
         throw new InsufficientBalanceApiException();
     }
     $this->connectToStorageInternalWorker->connect()->update(['mobile' => $mobile, 'uniqueness' => $uniqueness], ['$set' => ['topics' => $topics], '$inc' => ['balance' => $resellPackage['amount']]]);
     $this->decreaseBalanceInternalWorker->decrease($uniqueness, $resellPackage['amount']);
     $this->enqueueMessageApiWorker->enqueue($mobile, sprintf("Tu telefono se ha recargado con %s sms para seguir recibiendo noticias.", $resellPackage['amount']));
     $this->logOperationInternalWorker->logRecharge($mobile, $uniqueness, $topics, $subscription['trial'], $subscription['balance'], $resellPackage['amount'], time());
     try {
         $this->deleteLowBalanceReminderLogInternalWorker->delete($mobile);
     } catch (NonExistentMobileInternalException $e) {
         // This subscription did not have a low balance reminder log
     }
 }
 /**
  * Collects subscriptions.
  *
  * @return \Iterator
  */
 public function collect()
 {
     return $this->connectToStorageInternalWorker->connect()->find()->fields(['_id' => 0]);
 }
 /**
  * Counts subscriptions by given uniqueness
  *
  * @param $uniqueness
  *
  * @return int
  */
 public function compute($uniqueness)
 {
     return $this->connectToStorageInternalWorker->connect()->find(['uniqueness' => $uniqueness])->count();
 }
 /**
  * Collects subscriptions from given uniqueness.
  *
  * @param string $uniqueness
  *
  * @return \Iterator An array of subscriptions with the following keys:
  *                   mobile, uniqueness, alias, topics, balance and active
  */
 public function collect($uniqueness)
 {
     return $this->connectToStorageInternalWorker->connect()->find(['uniqueness' => $uniqueness])->fields(['_id' => 0, 'order' => 0])->sort(['order' => -1]);
 }
 /**
  * Collects subscriptions with low balance.
  *
  * @return \Iterator An array of subscriptions with the following keys:
  *                   mobile, uniqueness, alias, topics, balance and active
  */
 public function collect()
 {
     return $this->connectToStorageInternalWorker->connect()->find(['trial' => ['$lte' => 3], 'balance' => ['$lte' => 3]])->fields(['_id' => 0, 'order' => 0])->sort(['order' => -1]);
 }