Ejemplo n.º 1
0
 /**
  * Get array of up to 30
  * similar questions, create html block from
  * these questions and save in Question
  * under the sim_q key
  *
  * @param \Lampcms\Question $Question
  *
  * @throws \Exception
  * @internal param bool $ret indicates that this is a retry
  *           and prevents against retrying calling itself
  *           more than once
  *
  * @return object $this
  */
 public function getSimilarQuestions(\Lampcms\Question $Question)
 {
     if (!extension_loaded('pdo_mysql')) {
         d('pdo or pdo_mysql not loaded skipping parsing of similar items');
         return $this;
     }
     $qid = (int) $this->Question['_id'];
     $term = $Question['title'];
     $html = '';
     $aRes = array();
     $sql = "SELECT\r\n\t\t\t\tqid, \r\n\t\t\t\ttitle, \r\n\t\t\t\turl, \r\n\t\t\t\tintro\r\n\t\t\t\tFROM question_title\r\n\t\t\t\tWHERE \r\n\t\t\t\tqid != :qid\r\n \t\t\t\tAND " . self::BY_TITLE . "\r\n\t\t\t\tLIMIT 30";
     d('$sql: ' . $sql);
     try {
         $sth = $this->Registry->Db->makePrepared($sql);
         $sth->bindParam(':qid', $qid, \PDO::PARAM_INT);
         $sth->bindParam(':subj', $term, \PDO::PARAM_STR);
         $sth->execute();
         $aRes = $sth->fetchAll();
         d('found ' . count($aRes) . ' similar questions ' . print_r($aRes, 1));
         if (!empty($aRes)) {
             $html = \tplSimquestions::loop($aRes);
             $s = '<div id="sim_questions" class="similars">' . $html . '</div>';
             d('html: ' . $s);
             $Question->offsetSet('sim_q', $s);
             $Question->save();
         }
     } catch (\Exception $e) {
         $err = 'Exception: ' . get_class($e) . ' Unable to select mysql because: ' . $e->getMessage() . ' Err Code: ' . $e->getCode() . ' trace: ' . $e->getTraceAsString();
         d('mysql error: ' . $err);
         if ('42S02' === $e->getCode()) {
             if (true === TitleTagsTable::create($this->Registry)) {
                 return $this;
             } else {
                 throw $e;
             }
         } else {
             throw $e;
         }
     }
     return $this;
 }
Ejemplo n.º 2
0
    /**
     * When question is edited in any way we will
     * run this method to also update
     * the index.
     *
     * @param \Lampcms\Question $Question $Question
     *
     * @throws \Exception
     * @return \Lampcms\Modules\Search\IndexerMySQL
     */
    public function updateQuestion(\Lampcms\Question $Question)
    {
        if (!extension_loaded('pdo_mysql')) {
            d('pdo_mysql not loaded ');
            return $this;
        }
        $res = false;
        $qid = $Question->offsetGet('_id');
        $title = $Question->offsetGet('title');
        $url = $Question->offsetGet('url');
        $intro = $Question->offsetGet('intro');
        $username = $Question['username'];
        $ulink = $Question['ulink'];
        $avatar = $Question['avtr'];
        $tags_html = $Question['tags_html'];
        $body = $Question['body'];
        d($qid . ' title: ' . $title . ' url: ' . $url . ' intro: ' . $intro);
        $sql = 'UPDATE question_title
		SET 
		title = :qtitle,
		q_body = :qbody,
		url = :qurl, 
		intro = :qintro, 
		username = :username,
		userlink = :userlink,
		avtr = :avatar,
		tags_html = :tags_html
		WHERE qid = :qid';
        try {
            $sth = $this->Registry->Db->makePrepared($sql);
            $sth->bindParam(':qid', $qid, \PDO::PARAM_INT);
            $sth->bindParam(':qtitle', $title, \PDO::PARAM_STR);
            $sth->bindParam(':qbody', $body, \PDO::PARAM_STR);
            $sth->bindParam(':qurl', $url, \PDO::PARAM_STR);
            $sth->bindParam(':qintro', $intro, \PDO::PARAM_STR);
            $sth->bindParam(':tags_html', $tags_html, \PDO::PARAM_STR);
            $sth->bindParam(':username', $username, \PDO::PARAM_STR);
            $sth->bindParam(':userlink', $ulink, \PDO::PARAM_STR);
            $sth->bindParam(':avatar', $avatar, \PDO::PARAM_STR);
            $res = $sth->execute();
        } catch (\Exception $e) {
            $err = 'Exception: ' . get_class($e) . ' Unable to insert into mysql because: ' . $e->getMessage() . ' Err Code: ' . $e->getCode() . ' trace: ' . $e->getTraceAsString();
            d('mysql error: ' . $err);
            if ('42S02' === $e->getCode()) {
                if (true === TitleTagsTable::create($this->Registry)) {
                    $this->indexTitle($Question);
                }
            } else {
                throw $e;
            }
        }
        d('res: ' . $res);
        return $this;
    }
Ejemplo n.º 3
0
 /**
  * Get html div with answers for this one question,
  * sorted according to param passed in request
  *
  * Enclose result in <div> and add pagination to bottom
  * of div if there is any pagination necessary!
  *
  * @todo add skip() and limit() to cursor
  *       in order to use pagination.
  *
  * @param Question $Question
  *
  * @param string   $result desired format of result. Possible
  *                         options are: html, array or json object
  *
  *
  *
  * @throws Exception
  * @return string html block
  */
 public function getAnswers(Question $Question, $result = 'html')
 {
     $qid = $Question[Schema::PRIMARY];
     $url = $Question['url'];
     $pageID = $this->Registry->Router->getPageID();
     d('url: ' . $url . ' $pageID: ' . $pageID);
     $this->pagetPath = $Question->getUrl() . '/';
     $urlParts = $this->Registry->Ini->getSection('URI_PARTS');
     $cond = $this->Registry->Router->getSegment(3, 's', $urlParts['SORT_RECENT']);
     d('cond: ' . $cond);
     $noComments = false === (bool) $this->Registry->Ini->MAX_COMMENTS;
     d('no comments: ' . $noComments);
     $aFields = $noComments || false === (bool) $this->Registry->Ini->SHOW_COMMENTS ? array('comments' => 0) : array();
     /**
      * Extra security validation,
      * IMPORTANT because we should never use
      * anything in Mongo methods directly from
      * user input
      */
     if (!in_array($cond, array($urlParts['SORT_RECENT'], $urlParts['SORT_BEST'], $urlParts['SORT_OLDEST']))) {
         throw new Exception('Invalid value of param "cond" was: ' . $cond);
     }
     $where = array(Schema::QUESTION_ID => $qid);
     /**
      * Important as of version 0.2 no longer using i_del_ts
      * as indicator of deleted status - instead using i_status
      */
     if (!$this->Registry->Viewer->isModerator()) {
         d('not moderator. Get only questions with status 1');
         $where[Schema::RESOURCE_STATUS_ID] = Schema::POSTED;
     } else {
         $where[Schema::RESOURCE_STATUS_ID] < Schema::DELETED;
     }
     switch ($cond) {
         case $urlParts['SORT_RECENT']:
             /**
              * Accepted answer will always be the first one,
              * then most recently modified
              */
             $sort = array(Schema::IS_ACCEPTED => -1, Schema::LAST_MODIFIED_TIMESTAMP => -1);
             break;
         case $urlParts['SORT_OLDEST']:
             $sort = array(Schema::CREATED_TIMESTAMP => 1);
             break;
         case $urlParts['SORT_BEST']:
         default:
             /**
              * Accepted answer will be first
              * then most highly voted
              */
             $sort = array(Schema::IS_ACCEPTED => -1, Schema::VOTES_SCORE => -1);
     }
     $cursor = $this->Registry->Mongo->ANSWERS->find($where, $aFields);
     d('$cursor: ' . gettype($cursor));
     $cursor->sort($sort);
     $oPager = Paginator::factory($this->Registry);
     $oPager->paginate($cursor, $this->Registry->Ini->PER_PAGE_ANSWERS, array('path' => $this->pagetPath . $cond, 'append' => false, 'currentPage' => $pageID));
     $pagerLinks = $oPager->getLinks();
     $ownerId = $Question[Schema::POSTER_ID];
     $showLink = $ownerId > 0 && ($this->Registry->Viewer->isModerator() || $ownerId == $this->Registry->Viewer->getUid());
     $noComments = $noComments ? ' nocomments' : '';
     $func = function (&$a) use($showLink, $noComments) {
         /**
          * Don't show Accept link for
          * already accepted answer
          */
         if (!$a['accepted']) {
             if ($showLink) {
                 $a['accept_link'] = '<a class="accept ttt" title="@@Click to accept this as best answer@@" href="{_WEB_ROOT_}/{_accept_}/' . $a['_id'] . '">@@Accept@@</a>';
             }
         } else {
             $a['accepted'] = '<img src="{_IMAGE_SITE_}{_DIR_}/images/accepted.png" alt="@@Best answer@@" class="ttt" title="@@Owner of the question accepted this as best answer@@">';
         }
         $a['nocomments'] = $noComments;
         $a['edited'] = '@@Edited@@';
     };
     /**
      * Create div with answers, append pagination links
      * to bottom and return the whole div block
      */
     $answers = \tplAnswer::loop($cursor, true, $func) . $pagerLinks;
     return $answers;
 }
Ejemplo n.º 4
0
 /**
  * @depends testSetBestAnswer
  *
  */
 public function testSetLatestAnswer()
 {
     $User = new MockUser($this->Question->getRegistry());
     $Answer = new MockAnswer($this->Question->getRegistry());
     $this->Question->setLatestAnswer($User, $Answer);
     $a = $this->Question['a_latest'];
     $this->assertTrue(is_array($a[0]));
     $this->assertEquals(1, count($a));
     $this->assertEquals('<a href="/users/26/ladada">John D Doe</a>', $a['0']['u']);
     $this->assertEquals(513, $a['0']['id']);
     $Answer['_id'] = 999;
     $User['username'] = '******';
     $User['_id'] = 999999;
     $Answer->setSaved();
     $User->setSaved();
     $this->Question->setLatestAnswer($User, $Answer);
     $a = $this->Question['a_latest'];
     $this->assertTrue(is_array($a[0]));
     $this->assertEquals(2, count($a));
     $this->assertEquals('<a href="/users/999999/Dude">John D Doe</a>', $a['0']['u']);
     $this->assertEquals(999, $a['0']['id']);
     $this->assertEquals('<a href="/users/26/ladada">John D Doe</a>', $a['1']['u']);
     $this->assertEquals(513, $a['1']['id']);
     $this->Question->insert();
     $Question = new Question($this->Question->getRegistry());
     $Question->by_id(510);
     $a = $Question['a_latest'];
     $this->assertEquals(999, $a['0']['id']);
 }
Ejemplo n.º 5
0
 /**
  * When question is deleted
  * then decrease i_qcount but do it in such a way
  * that it cannot go below zero
  * Also if deleted question happends to be the one in the 'a_latest'
  * then also remove a_latest as well as set i_qid to 0
  *
  * @todo if a_latest is removed we really
  * need to replace it with another question
  * that is the "new latest" which would be one
  * posted before this one in the same category
  *
  * @param \Lampcms\Question $Q
  *
  * @return $this
  */
 public function removeQuestion(\Lampcms\Question $Q)
 {
     $id = $Q->getCategoryId();
     if ($id > 0) {
         $qid = $Q->getResourceId();
         $this->Mongo->CATEGORY->update(array('id' => $id, 'i_qcount' => array('$gt' => 0)), array('$inc' => array('i_qcount' => -1)));
         $this->Mongo->CATEGORY->update(array('id' => $id, 'i_qid' => $qid), array('$set' => array('i_qid' => 0, 'a_latest' => null)));
     }
     return $this;
 }
Ejemplo n.º 6
0
 /**
  * When question is deleted
  * then decrease i_qcount but do it in such a way
  * that it cannot go below zero
  * Also if deleted question happends to be the one in the 'a_latest'
  * then also remove a_latest as well as set i_qid to 0
  *
  * @todo if a_latest is removed we really
  *       need to replace it with another question
  *       that is the "new latest" which would be one
  *       posted before this one in the same category
  *
  * @param \Lampcms\Question $Q
  *
  * @return $this
  */
 public function removeQuestion(\Lampcms\Question $Q)
 {
     $id = $Q->getCategoryId();
     $qid = $Q->getResourceId();
     $this->removeQuestionById($qid, $id);
     return $this;
 }