/**
  * Post a Link to this question or answer
  * To User's Facebook Wall
  *
  */
 protected function post()
 {
     try {
         $reward = \Lampcms\Points::SHARED_CONTENT;
         $User = $this->Registry->Viewer;
         $oFB = $this->Registry->Facebook;
         $Resource = $this->obj;
         $Mongo = $this->Registry->Mongo;
         $logo = !empty($this->aFB['SITE_LOGO']) ? $this->aFB['SITE_LOGO'] : null;
         /**
          * @todo Translate String(s) of caption
          * It appears on Facebook Wall under the link
          * @var string
          */
         $caption = $this->obj instanceof \Lampcms\Question ? 'Please click if you can answer this question' : 'I answered this question';
         $description = Utf8String::factory($this->obj['b'], 'utf-8', true)->asPlainText()->valueOf();
     } catch (\Exception $e) {
         d('Unable to post to facebook because of this exception: ' . $e->getMessage() . ' in file: ' . $e->getFile() . ' on line: ' . $e->getLine());
         return;
     }
     $func = function () use($oFB, $Resource, $User, $reward, $Mongo, $logo, $caption, $description) {
         $result = null;
         $aData = array('link' => $Resource->getUrl(), 'name' => $Resource['title'], 'message' => $caption, 'description' => $description);
         if (!empty($logo) && 'http' == substr($logo, 0, 4)) {
             $aData['picture'] = $logo;
         }
         try {
             $result = $oFB->postUpdate($User, $aData);
         } catch (\Exception $e) {
             // does not matter
         }
         if (!empty($result) && false !== ($decoded = json_decode($result, true))) {
             /**
              * If status is OK
              * then reward the user with points!
              */
             if (!empty($decoded['id'])) {
                 $status_id = (string) $decoded['id'];
                 $User->setProfitPoint($reward);
                 /**
                  * Now need to also record Facebook id
                  * to FB_STATUSES collection
                  */
                 try {
                     /**
                      * Also save fb_status to QUESTIONS or ANSWERS
                      * collection.
                      * This way later on (maybe way later...)
                      * We can add a function so that if user edits
                      * Post on the site we can also edit it
                      * on Tumblr via API
                      * 
                      */
                     $Resource['fb_status'] = $status_id;
                     $Resource->save();
                 } catch (\Exception $e) {
                     if (function_exists('e')) {
                         e('Unable to save data to FB_STATUSES collection because of ' . $e->getMessage() . ' in file: ' . $e->getFile() . ' on line: ' . $e->getLine());
                     }
                 }
             }
         }
     };
     \Lampcms\runLater($func);
 }
Example #2
0
 /**
  * Send registration email to new user
  * Email will contain activation link
  * and instructions to activate the account
  *
  * @return Register
  */
 protected function sendActivationEmail()
 {
     $Tr = $this->Registry->Tr;
     $activationLink = $this->makeActivationLink();
     $siteName = $this->Registry->Ini->SITE_NAME;
     $body = $Tr->get('email.body.registration', array('{site_title}' => $siteName, '{username}' => $this->username, '{password}' => $this->pwd, '{link}' => $activationLink));
     $body = \Lampcms\Utf8String::leftAlign($body, 2);
     $subject = $Tr->get('email.subject.registration', array('{site_title}' => $siteName));
     /**
      * By default Mailer::mail sends email from shutdown function (returns immediately, sends later)
      */
     $this->Registry->Mailer->mail($this->email, $subject, $body);
     return $this;
 }
Example #3
0
 /**
  * Get count of words in this html document
  * This is the right way to get word count
  * from HTML doc. The simple way of strip_tags and
  * then explode by spaces will not work if
  * html string is just one long
  * string run together without white spaces
  * and using regex is usually not the best way
  * to deal with html string.
  *
  * Each Text Node element is then treated
  * as separate UTF8String object
  *
  * This way each text node is split by UTF-8 specific word
  * delimiters, making it return correct word count
  * for Any type of language (not only splitting by spaces but
  * by other accepted delimiters)
  *
  * The resulting word count will be accurate for arabic, chinese,
  * and probably all other languages
  *
  * @return int count of words in this html string
  */
 public function getWordsCount()
 {
     $count = 0;
     $Nodes = $this->getTextNodes();
     $len = $Nodes->length;
     if (!$Nodes || 0 === $len) {
         return 0;
     }
     for ($i = 0; $i < $len; $i += 1) {
         $UTF8String = Utf8String::stringFactory($Nodes->item($i)->data, 'utf-8', true);
         $count += $UTF8String->getWordsCount();
     }
     return $count;
 }
 /**
  *
  * What if email address provided from Facebook
  * already belongs to some other user?
  *
  * This would mean that existing user is just
  * trying to signup with Facebook.
  *
  * In this case we should allow it but ONLY create
  * a record in the USERS_FACEBOOK table and use users_id
  * of use that we find by email address
  *
  * and then also insert avatar_external into USERS
  *
  * @todo create username for user based on Facebook username
  * Facebook does not really have username, so we can use fn_ln
  *
  */
 protected function createNewUser()
 {
     $extAuth = new \Lampcms\ExternalAuth($this->Registry);
     d('cp');
     $this->Registry->Mongo->USERS->ensureIndex(array('fb_id' => 1));
     /**
      * Time zone offset in seconds
      * @var int
      */
     $tzo = array_key_exists('timezone', $this->aFbUserData) ? $this->aFbUserData['timezone'] * 3600 : Cookie::get('tzo', 0);
     /**
      * User language
      * @var string
      */
     $lang = !empty($this->aFbUserData['locale']) ? \strtolower(\substr($this->aFbUserData['locale'], 0, 2)) : $this->Registry->getCurrentLang();
     /**
      * User locale
      * @var string
      */
     $locale = !empty($this->aFbUserData['locale']) ? $this->aFbUserData['locale'] : $this->Registry->Locale->getLocale();
     $this->tempPassword = String::makePasswd();
     /**
      * Sid value use existing cookie val
      * if possible, otherwise create a new one
      * @var string
      */
     $sid = false === ($sid = Cookie::getSidCookie()) ? String::makeSid() : $sid;
     $displayName = !empty($this->aFbUserData['name']) ? $this->aFbUserData['name'] : $this->aFbUserData['first_name'] . ' ' . $this->aFbUserData['last_name'];
     $username = $extAuth->makeUsername($displayName);
     /**
      * Create new record in USERS table
      * do this first because we need uid from
      * newly created record
      */
     $aUser = array('username' => $username, 'username_lc' => \mb_strtolower($username, 'utf-8'), 'fn' => $this->aFbUserData['first_name'], 'ln' => $this->aFbUserData['last_name'], 'rs' => $sid, 'email' => Utf8String::factory($this->aFbUserData['email'])->toLowerCase()->valueOf(), 'fb_id' => (string) $this->aFbUserData['id'], 'fb_token' => $this->aFbUserData['token'], 'pwd' => String::hashPassword($this->tempPassword), 'avatar_external' => 'http://graph.facebook.com/' . $this->aFbUserData['id'] . '/picture', 'i_reg_ts' => time(), 'date_reg' => date('r'), 'role' => 'external_auth', 'lang' => $lang, 'i_pp' => 1, 'tz' => TimeZone::getTZbyoffset($tzo), 'i_fv' => false !== ($intFv = Cookie::getSidCookie(true)) ? $intFv : time());
     if (!empty($this->aFbUserData['gender'])) {
         $aUser['gender'] = 'male' === $this->aFbUserData['gender'] ? 'M' : 'F';
     }
     $aUser = \array_merge($this->Registry->Geo->Location->data, $aUser);
     if (!empty($this->aFbUserData['locale'])) {
         $aUser['locale'] = $this->aFbUserData['locale'];
     }
     if (!empty($this->aFbUserData['link'])) {
         $aUser['fb_url'] = $this->aFbUserData['link'];
     }
     d('aUser: '******'$this->User after insert: ' . print_r($this->User->getArrayCopy(), 1));
     $this->Registry->Dispatcher->post($this->User, 'onNewUser');
     $this->Registry->Dispatcher->post($this->User, 'onNewFacebookUser');
     d('cp');
     $this->saveEmailAddress();
     d('cp');
     \Lampcms\PostRegistration::createReferrerRecord($this->Registry, $this->User);
     return $this;
 }
Example #5
0
 /**
  * (non-PHPdoc)
  *
  * @see Lampcms.WebPage::main()
  */
 protected function main()
 {
     /**
      * Do NOT run urldecode() on request string
      * as it's already decoded because it uses
      *  $_GET as underlying array, and php
      *  already decodes $_GET or $_POST vars
      */
     try {
         $term = $this->Registry->Router->getSegment(2);
         $this->term = Utf8String::stringFactory(\urldecode($term));
     } catch (\Lampcms\Uri\SegmentNotFoundException $e) {
         $this->term = $this->Registry->Request->getUTF8('q');
     }
     $this->safeTerm = \str_replace(array('<', '>'), array('&lt;', '&gt'), $this->term->valueOf());
     $this->aPageVars['qheader'] = '<h1>@@Search results for@@: ' . $this->safeTerm . '</h1>';
     $this->aPageVars['title'] = '@@Questions matching@@ &#39;' . $this->safeTerm . '&#39;';
     d('$this->term: ' . $this->term);
     $this->Search = SearchFactory::get($this->Registry);
     $this->Search->search($this->term);
     $this->makeTopTabs()->makeInfo()->makeBody();
 }
Example #6
0
 /**
  * Find data in Mongo
  * and create array of $this->aData
  *
  * @return object $this
  */
 protected function getData()
 {
     $q = $_GET['q'];
     d('$q: ' . $q);
     $q = Utf8String::stringFactory($q);
     $aTokens = TitleTokenizer::factory($q)->getArrayCopy();
     if (!empty($aTokens)) {
         d('looking for something');
         try {
             $cur = $this->Registry->Mongo->QUESTIONS->find(array('a_title' => array('$all' => $aTokens), 'a_deleted' => null), array('_id' => true, 'title' => true, 'url' => true, 'intro' => true, 'hts' => true, 'status' => true, 'i_ans' => true, 'ans_s' => true))->sort(array('status' => 1, 'i_ans' => -1))->limit(12);
             $this->aData = iterator_to_array($cur, false);
             d('$this->aData: ' . print_r($this->aData, 1));
         } catch (\MongoException $e) {
             d('MongoException: ' . $e->getMessage() . ' aTokens was: ' . \print_r($this->aTokens, 1));
         }
     }
     return $this;
 }
Example #7
0
 /**
  * Make new value of title
  *
  * @param string $title
  *
  * @return object of type Utf8String
  */
 protected function makeTitle($title)
 {
     $oTitle = Utf8String::stringFactory($title)->htmlentities()->trim();
     d('$oTitle ' . $oTitle);
     return $oTitle;
 }
Example #8
0
 /**
  * Extract value of tags from
  * query string and turn into array
  * runs value of Request through urldecode because
  * unicode tags would be percent-encoded in the url
  *
  * @param string $unasweredSortSection flag indicated that request is for
  * unanswered tagged items not just tagged items.
  * If a string is passed it's a value of the COND_TAGGED in the URI_PARTS section in !config.ini
  * This would mean that
  * structure of the uri is in the form of {_UNANSWERED_}/{_COND_TAGGED_}/all+tags+here
  *
  * @return array of tags passed in query string
  */
 protected function getTags($unasweredSortSection = null)
 {
     if (empty($this->aTags)) {
         $cname = $this->Router->getCalledControllerName();
         if ($unasweredSortSection) {
             $cname .= '/' . $unasweredSortSection;
         }
         $cname = \preg_quote($cname, '/');
         /**
          * And now a workaround
          * for the genocidal RewriteRule bug
          * that obliterates the urlencoded chars
          * during the rewrite
          * so instead we must work directly
          * with $_SERVER['REQUEST_URI']
          * $_SERVER['REQUEST_URI'] is consistently
          * the same on Apache and on Lighttpd when
          * php is run as fastcgi
          * The rewrite on Lighttpd does not have
          * this genocidal bug, but for consistency
          * we still working with $_SERVER['REQUEST_URI']
          * regardless of the server
          */
         if (!empty($_SERVER) && !empty($_SERVER['REQUEST_URI'])) {
             /**
              * Must use regex because REQUEST_URI
              * may contain also a pageID after the last /
              * so must extract part from
              * between /tagged/ and next /
              *
              * $r is something like this: /tagged/tag%2B%2B/
              */
             $r = $_SERVER['REQUEST_URI'];
             $m = \preg_match('/\\/' . $cname . '\\/([^\\/]+)([\\/]{0,1})/i', $r, $matches);
             d('matches: ' . \json_encode($matches));
             if ($matches && !empty($matches[1])) {
                 $tags = $matches[1];
                 d('tags: ' . $tags);
                 $this->tags = \urldecode($tags);
             }
         } else {
             /**
              * That's hopefully is OK
              * because Apache always has REQUEST_URI
              * and if it's not available here
              * then hopefully this is not an Apache server
              * and it's possible the rewrite worked without this bug
              */
             d('no REQUEST_URI available');
             $tags = $this->Request['tags'];
             $this->tags = \urldecode($tags);
         }
         $this->rawTags = $this->tags;
         /**
          * Important step to prevent
          * script or html injection in url GET string
          * Cannot use htmlspecialchars because we don't want to
          * also encode the &
          *
          */
         $this->tags = \str_replace(array('<', '>'), array('&lt;', '&gt;'), $this->tags);
         $this->title = $this->tags;
         if (empty($this->tags)) {
             return array();
         }
         /**
          * $this->tags are now urldecoded
          * If this does not work well them try
          * to use $tags instead
          */
         $Utf8Tags = Utf8String::stringFactory($this->tags);
         /**
          * @todo the this->tags now have htmlspecialchars
          *       which may not be what we want in this->aTags
          *       We probably want this->aTags to be raw tags just like
          *       they were submitted in request.
          *
          */
         $this->aTags = TagsTokenizer::factory($Utf8Tags)->getArrayCopy();
         d('aTags: ' . \json_encode($this->aTags));
     }
     return $this->aTags;
 }
 /**
  * Unlike normal WWW request, 
  * In API call we may not have 'tags' in Request,
  * so we need to fallback to default empty string here
  *
  * (non-PHPdoc)
  * @see Lampcms.SubmittedQuestionWWW::getUtf8Tags()
  */
 public function getUtf8Tags()
 {
     if (!isset($this->Tags)) {
         $tags = $this->Registry->Request->get('tags', 's', '');
         $this->Tags = Utf8String::factory($tags);
     }
     return $this->Tags;
 }
Example #10
0
 /**
  * Enforce min and max length of comment
  *
  * @todo Translate string
  *
  * @throws \Lampcms\Exception
  */
 protected function validateBody(Utf8String $Body)
 {
     $len = $Body->length();
     if ($len < 10) {
         /**
          * @todo
          * Translate String
          */
         throw new Exception('Ooopsy... Comment must be at least 10 characters long');
     }
     if ($len > 600) {
         throw new Exception('Oopsy... Comment must be at limited to 600 characters. Your comment is ' . $len . ' characters-long');
     }
     return $this;
 }
Example #11
0
 /**
  * Get value of segment as a Utf8String object
  *
  * @param      $segmentId
  * @param null $default
  *
  * @return object of type \Lampcms\Utf8String
  */
 public function getUTF8($segmentId, $default = null)
 {
     $res = $this->getSegment($segmentId, 's', $default);
     $ret = Utf8String::stringFactory($res);
     return $ret;
 }
 /**
  * @return object of type Utf8string representing
  * the title string of question
  */
 public function getTitle()
 {
     return Utf8String::stringFactory('Quick brown fox');
 }
Example #13
0
 /**
  * Translate the $item into $locale language
  *
  * @param string $locale
  * @param mixed string|object of type TranslatableInterface $item
  *
  * @return string translated string
  * @throws \Lampcms\DevException
  */
 public function translate($locale, $item)
 {
     if (is_string($item)) {
         return $item;
     }
     if (!is_object($item) || !$item instanceof TranslatableInterface) {
         throw new DevException('$item can only be a string or instance of TranslatableInterface. Was: ' . (!is_object($item) ? gettype($item) : get_class($item)));
     }
     $Tr = $this->getTranslator($locale);
     return \Lampcms\Utf8String::leftAlign($Tr->get($item->getString(), $item->getVars()));
 }
Example #14
0
 /**
  * Prepare the raw string before posting to Twitter
  * It will convert string to guaranteed utf8,
  * then strip html tags then truncate to 140 chars
  *
  * @param Utf8String $Message
  * @param string     $inReplyToId
  *
  * @internal param string $sMessage
  * @return array of response data from Twitter API
  */
 public function prepareAndPost(Utf8String $Message, $inReplyToId = null)
 {
     $body = $Message->htmlspecialchars()->truncate(140)->valueOf();
     return $this->postMessage($body, $inReplyToId);
 }
Example #15
0
 /**
  *
  * Set tags for this question
  * It will also update "a_edited" array
  * to record the retag action, records
  * user who retagged, and "Retag" as reason for edit
  * Will also update lastModified
  *
  * @param User  $user object User who retagged this question
  * @param array $tags array of tags
  *
  * @return \Lampcms\Question
  */
 public function retag(User $user, array $tags)
 {
     parent::offsetSet(Schema::TAGS_ARRAY, $tags);
     parent::offsetSet('tags_html', \tplQtags::loop($tags, false));
     $b = $this->offsetGet(Schema::BODY);
     d('b: ' . $b);
     $oHtmlParser = \Lampcms\String\HTMLStringParser::stringFactory(Utf8String::stringFactory($b, 'utf-8', true));
     $body = $oHtmlParser->unhilight()->hilightWords($tags)->valueOf();
     $this->offsetSet(Schema::BODY, $body);
     $this->setEdited($user, 'Retagged')->touch();
     return $this;
 }
Example #16
0
 /**
  * Enforce min and max length of comment
  *
  *
  * @param Utf8String $Body
  *
  * @throws AlertException
  * @return \Lampcms\CommentParser
  */
 protected function validateBody(Utf8String $Body)
 {
     $minChars = $this->Registry->Ini->MIN_COMMENT_CHARS;
     $maxChars = $this->Registry->Ini->MAX_COMMENT_CHARS;
     $len = $Body->length();
     if ($len < $minChars) {
         throw new AlertException('@@Comment is too short. Minimal length is@@' . ' ' . $minChars);
     }
     if ($len > $maxChars) {
         throw new AlertException('@@Comment is too long. Maximum number of characters is@@ ' . $maxChars);
     }
     return $this;
 }
Example #17
0
 /**
  * Set the URI String
  *
  * @param     string
  *
  * @return    string
  */
 public static function setUriString($str)
 {
     $str = Utf8String::stripLow($str);
     self::$uri = $str === '/' ? '' : $str;
     return self::$uri;
 }
 /**
  * Removes the tag name from the array of a_f_t
  * of User object and increases the i_f_t by one
  * if USER already follow this tag
  * also decreases the i_flwrs in QUESTION_TAGS collection
  * by one for this tag
  *
  *
  * @param User $User
  * @param string $tag
  * @return \Lampcms\FollowManager
  * @throws \InvalidArgumentException if $tag is not a string
  */
 public function unfollowTag(User $User, $tag)
 {
     if (!is_string($tag)) {
         throw new \InvalidArgumentException('$tag must be a string');
     }
     $tag = Utf8String::stringFactory($tag)->toLowerCase()->stripTags()->trim()->valueOf();
     $aFollowed = $User['a_f_t'];
     d('$aFollowed: ' . print_r($aFollowed, 1));
     if (false !== ($key = array_search($tag, $aFollowed))) {
         d('cp unsetting key: ' . $key);
         array_splice($aFollowed, $key, 1);
         $User['a_f_t'] = $aFollowed;
         $User->save();
         $this->Registry->Mongo->QUESTION_TAGS->update(array('tag' => $tag), array('$inc' => array('i_flwrs' => -1)));
         $this->Registry->Dispatcher->post($User, 'onTagUnfollow', array('tag' => $tag));
     } else {
         d('tag ' . $tag . ' is not among the followed tags of this userID: ' . $User->getUid());
     }
     return $this;
 }
 /**
  * Checks in username of twitter user
  * already exists in our regular USERS table
  * and if it does then prepends the @ to the username
  * otherwise returns twitter username
  *
  * The result is that we will use the value of
  * Twitter username as our username OR the
  *
  * @username
  *       if username is already taken
  *
  * @todo change this to use MONGO USERS and use something like
  * $any
  *
  * @param      $displayName
  * @param bool $isUtf8
  *
  * @return string the value of username that will
  */
 public function makeUsername($displayName, $isUtf8 = false)
 {
     d('going to auto_create username based on displayName: ' . $displayName);
     /**
      * Make 100% sure that displayName is in UTF8 encoding
      * Commenting this out for now since it was causing
      * a problem once.
      * So for now we going to trust that Facebook give us results
      * as a valid UTF-8 String
      */
     if (!$isUtf8) {
         $displayName = Utf8String::stringFactory($displayName)->valueOf();
     }
     $coll = $this->Registry->Mongo->USERS;
     $res = null;
     $username = null;
     $aUsernames = array(preg_replace('/\\s+/', '_', $displayName), preg_replace('/\\s+/', '.', $displayName), preg_replace('/\\s+/', '-', $displayName), preg_replace('/\\s+/', '', $displayName));
     $aUsernames = \array_unique($aUsernames);
     d('$aUsernames: ' . \json_encode($aUsernames, 1));
     for ($i = 0; $i < count($aUsernames); $i++) {
         $name = \mb_strtolower($aUsernames[$i], 'utf-8');
         $res = $coll->findOne(array(Schema::USERNAME_LOWERCASE => $name));
         d('$res: ' . \var_export($res, 1));
         if (empty($res)) {
             $username = $aUsernames[$i];
             break;
         }
     }
     /**
      * If still could not find username then
      * use brute force and try appending numbers
      * to username until succeed
      */
     if (null === $username) {
         $i = 1;
         do {
             $name = \mb_strtolower($aUsernames[0], 'utf-8') . $i;
             $res = $coll->findOne(array(Schema::USERNAME_LOWERCASE => $name));
             if (empty($res)) {
                 $username = $aUsernames[0] . $i;
             }
             d('$res: ' . \var_export($res, 1));
             $i += 1;
         } while (null === $username);
     }
     return $username;
 }