/**
  * It handles the case in which a user that already used a free trial,
  * try to get another free trial (that is not allowed)
  *
  * It also set the pc_user.has_requested_free_trial field
  *
  * @param PcUser $user
  * @param PcSubscriptionType $subscriptionType
  * @param bool $isGift (=false)
  * @param bool $isAutomatic (=false)
  * @param string $paypalTransactionId (='')
  * @return bool - false if a user who requested a free trial tries to get it again, true otherwise
  */
 public static function createOrExtendSupporterAccount(PcUser $user, PcSubscriptionType $subscriptionType, $isGift = false, $isAutomatic = false, $paypalTransactionId = '')
 {
     if ($subscriptionType->getId() == PcSubscriptionTypePeer::FREE_TRIAL) {
         if ($user->getHasRequestedFreeTrial()) {
             return false;
         } else {
             $user->setHasRequestedFreeTrial(1)->save();
         }
     }
     // 3 situations can happen:
     // 1) the user is not an supporter -> we add the record
     // 2) the user is still a supporter -> we extend the subscription from the last day of the current subscription
     // 3) the user used to be a supporter (the record is still in the table) but the subscription has expired -> we
     //    start a new subscription from today
     $startDate = null;
     $today = date("Y-m-d");
     $c = new Criteria();
     $c->add(PcSupporterPeer::USER_ID, $user->getId());
     $supporterAccount = PcSupporterPeer::doSelectOne($c);
     if (!$supporterAccount) {
         $supporterAccount = new PcSupporter();
         $supporterAccount->setUserId($user->getId());
         $startDate = $today;
     } else {
         $supporterAccountExpiryDate = $supporterAccount->getExpiryDate();
         if ($today > $supporterAccountExpiryDate) {
             $startDate = $today;
         } else {
             $startDate = $supporterAccountExpiryDate;
         }
     }
     $newExpiryDateTimestamp = $supporterAccount->getNewExpiryDateAfterSubscription($subscriptionType, $startDate);
     $supporterAccount->setExpiryDate(date("Y-m-d", $newExpiryDateTimestamp))->save();
     // recording the subscription
     $subscription = new PcSubscription();
     $subscription->setUserId($user->getId())->setSubscriptionTypeId($subscriptionType->getId())->setWasGift($isGift)->setWasAutomatic($isAutomatic)->setPaypalTransactionId($paypalTransactionId)->save();
     // sending email
     $email = $user->getEmail();
     $from = sfConfig::get('app_emailAddress_contact');
     $subject = sfConfig::get('app_subscriptionSuccess_emailSubject');
     $body = sfConfig::get('app_subscriptionSuccess_emailBody');
     $replyTo = sfConfig::get('app_emailAddress_director');
     PcUtils::sendEmail($email, $subject, $body, $from, $replyTo);
     // creating task in the Inbox
     $user->addToInbox(__('ACCOUNT_SUBSCRIPTION_INBOX_MESSAGE') . ' ' . $supporterAccount->getExpiryDate('j F Y') . '.');
     return true;
 }
 public function executeDeleteAccount(sfWebRequest $request)
 {
     $user = PcUserPeer::getLoggedInUser();
     $this->form = new DeleteAccountForm();
     $reasons = $this->form->getReasons();
     $fields = array();
     if ($request->isMethod('post')) {
         $this->form->bind($request->getParameter('deleteAccount'));
         if ($this->form->isValid()) {
             $fields = $request->getParameter('deleteAccount');
             $message = $reasons[$fields['reason']] . "\n XX \n" . $fields['info'];
             $to = sfConfig::get('app_emailAddress_contact');
             // we need to add a 'random' code otherwise GMail groups all of them together
             $subject = 'Account deletion ' . date('YmdHis');
             PcUtils::sendEmail($to, $subject, $message, $to, PcUserPeer::getLoggedInUser()->getEmail());
             $emailAddressForDeletedAccounts = 'deleted_' . PcUtils::generateRandomString(32) . '@plancake.com';
             $user->setEmail($emailAddressForDeletedAccounts)->save();
             sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent('userSetEmail', 'user.set_email', array('user' => $user)));
             CustomAuth::logout($this->getUser());
             $this->redirect(sfContext::getInstance()->getController()->genUrl('@homepage'));
         }
     }
     $this->user = $user;
 }
 public function executeSubmitArticle(sfWebRequest $request)
 {
     $this->form = new SubmitArticleForm();
     $user = PcUserPeer::getLoggedInUser();
     $this->submitted = false;
     if ($request->isMethod('post')) {
         $this->form->bind($request->getParameter('article'), $request->getFiles('article'));
         if ($this->form->isValid()) {
             $file = $this->form->getValue('file');
             $extension = $file->getExtension($file->getOriginalExtension());
             $fileFullPath = '/tmp/article_' . time('Y-m-d-H-i-s') . $extension;
             try {
                 $file->save($fileFullPath);
                 PcUtils::sendEmail(sfConfig::get('app_site_adminUserEmails'), 'New article', 'New article', sfConfig::get('app_site_adminUserEmails'), $user->getEmail(), $fileFullPath);
             } catch (Exception $e) {
                 unlink($fileFullPath);
                 throw $e;
             }
             unlink($fileFullPath);
             $this->submitted = true;
         }
     }
 }
 /**
  * Register a new user
  *
  * @param string $email - the email address
  * @param string $password - the plain password (no encryption)
  * @param string $lang - if it is null or empty, the language will be detected from the header of the request
  * @param string $preferredLang - this should be a 2-char abbreviation of the lang the user wants,
  *         among the ones in the main app.yml config file
  * @param string $tzLabel - a timezone label as in the PcTimezone db table
  * @param integer $dstOn (1 or 0) - whether or not the dst for the user is on
  * @param boolen $joinNewsletter(=false) - whether the user decided to join our newsletter
  * @param boolen $sendActivationEmail(=true) - whether to send the activation email  
  * @return boolean|PcUser false is a user with that email already exists, the PcUser object otherwise
  */
 public static function registerNewUser($email, $password, $lang, $preferredLang, $tzLabel, $dstOn, $joinNewsletter = false, $sendActivationEmail = true)
 {
     if (self::emailExist($email)) {
         return false;
     }
     $newUser = new PcUser();
     $newUser->setEmail($email);
     $newUser->setPassword($password);
     $newUser->setAwaitingActivation(1);
     if ($joinNewsletter) {
         $newUser->setNewsletter(1);
     }
     $newUser->save();
     // Dealing with timezone
     $newUser->setDstActive($dstOn);
     $c = new Criteria();
     $c->add(PcTimezonePeer::LABEL, $tzLabel, Criteria::EQUAL);
     $timezone = PcTimezonePeer::doSelectOne($c);
     if (!is_object($timezone)) {
         // set to a default one
         $timezone = PcTimezonePeer::retrieveByPK(21);
     }
     $newUser->setTimezoneId($timezone->getId());
     // Dealing with formats
     // _ time format: the countries with the majority of our users are using the
     //   12H format, thus we can leave the default
     // _ for the date format we check whether they are in USA
     // _ for the first day of the week, we check whether they are in USA
     $dateFormatId = 3;
     $weekStart = 1;
     // from Monday
     $tzOffset = $timezone->getOffset();
     if ($tzOffset <= -300 && $tzOffset >= -450) {
         $dateFormatId = 4;
         $weekStart = 0;
         // from Sunday
     }
     $newUser->setDateFormat($dateFormatId);
     $newUser->setWeekStart($weekStart);
     if ($lang != null && $lang !== '') {
         $newUser->setLanguage($lang);
     } else {
         $newUser->setLanguage(PcUtils::getVisitorAcceptLanguage());
     }
     $availableLangs = PcLanguagePeer::getAvailableLanguageAbbreviations();
     if (in_array($preferredLang, $availableLangs)) {
         $newUser->setPreferredLanguage($preferredLang);
     } else {
         $newUser->setPreferredLanguage(SfConfig::get('app_site_defaultLang'));
     }
     $newUser->setIpAddress(PcUtils::getVisitorIPAddress());
     if ($sessionEntryPoint = sfContext::getInstance()->getUser()->getAttribute('session_entry_point')) {
         $newUser->setSessionEntryPoint($sessionEntryPoint);
     }
     if ($sessionReferral = sfContext::getInstance()->getUser()->getAttribute('session_referral')) {
         $newUser->setSessionReferral($sessionReferral);
     }
     $newUser->save();
     // Creating system lists
     $inboxList = new PcList();
     $inboxList->setIsInbox(1)->setTitle(__('ACCOUNT_LISTS_INBOX'))->setCreator($newUser)->save();
     $todoList = new PcList();
     $todoList->setIsTodo(1)->setTitle(__('ACCOUNT_LISTS_TODO'))->setCreator($newUser)->save();
     // Creating default contexts
     $context = new PcUsersContexts();
     $context->setPcUser($newUser)->setContext(__('ACCOUNT_TAGS_DEFAULT_HOME'))->save();
     $context = new PcUsersContexts();
     $context->setPcUser($newUser)->setContext(__('ACCOUNT_TAGS_DEFAULT_ERRANDS'))->save();
     $context = new PcUsersContexts();
     $context->setPcUser($newUser)->setContext(__('ACCOUNT_TAGS_DEFAULT_COMPUTER'))->save();
     // Creating some tasks for the inbox
     $newUser->addToInbox(__('ACCOUNT_MISC_WELCOME_TASK'));
     // creating Plancake email address
     $newUser->generateAndStorePlancakeEmailAddress();
     // I need to use a token for the activation of their account
     $token = '';
     $c = new Criteria();
     $c->add(PcActivationTokenPeer::USER_ID, $newUser->getId(), Criteria::EQUAL);
     $tokenEntry = PcActivationTokenPeer::doSelectOne($c);
     if (is_object($tokenEntry)) {
         $token = $tokenEntry->getToken();
     } else {
         $secret = sfConfig::get('app_registration_secret');
         // token doesn't need to be 32-char long. It is better to keep it short
         // so there will be less chance the email client will break the link into 2 lines
         $token = substr(md5($newUser->getId() . $secret . time()), 0, 14);
         $tokenEntry = new PcActivationToken();
         $tokenEntry->setUserId($newUser->getId());
         $tokenEntry->setToken($token);
         $tokenEntry->save();
     }
     // now we can send the email
     if ($sendActivationEmail) {
         $link = sfContext::getInstance()->getController()->genUrl('@activation?t=' . $token, true);
         $from = sfConfig::get('app_emailAddress_contact');
         $subject = 'Plancake - ' . __('WEBSITE_REGISTRATION_EMAIL_SUBJECT');
         $body = sprintf(__('WEBSITE_REGISTRATION_EMAIL_BODY'), $link);
         PcUtils::sendEmail($email, $subject, $body, $from);
     }
     $newUser->refreshLatestBlogAccess();
     sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent($newUser, 'user.sign_up', array('user' => $newUser, 'plainPassword' => $password)));
     return $newUser;
 }
 /**
  * Sends an email to reset the password.
  * At this point we should be already sure the email address is valid
  *
  * @param string $email - the email address
  */
 public static function sendPasswordForgotten($email)
 {
     $requestingUser = PcUserPeer::getUserByEmail($email);
     if (!is_object($requestingUser)) {
         throw new Exception('Couldn\'t send the password forgotten email. Problems while creating the user object.');
     }
     // I need to use a token
     $token = '';
     $c = new Criteria();
     $c->add(PcPasswordResetTokenPeer::USER_ID, $requestingUser->getId(), Criteria::EQUAL);
     $tokenEntry = PcPasswordResetTokenPeer::doSelectOne($c);
     if (is_object($tokenEntry)) {
         $token = $tokenEntry->getToken();
     } else {
         $secret = sfConfig::get('app_forgottenPassword_secret');
         // token doesn't need to be 32-char long. It is better to keep it short
         // so there will be less chance the email client will break the link into 2 lines
         $token = substr(md5($requestingUser->getId() . $secret . time()), 0, 14);
         $tokenEntry = new PcPasswordResetToken();
         $tokenEntry->setUserId($requestingUser->getId());
         $tokenEntry->setToken($token);
         $tokenEntry->save();
     }
     // now we can send the email
     $link = sfContext::getInstance()->getController()->genUrl('@password-reset?t=' . $token, true);
     $from = sfConfig::get('app_emailAddress_contact');
     $subject = __('WEBSITE_FORGOTTEN_PSW_EMAIL_SUBJECT');
     $body = sprintf(__('WEBSITE_FORGOTTEN_PSW_EMAIL_BODY'), $link);
     PcUtils::sendEmail($email, $subject, $body, $from);
 }