Changeset 40
- Timestamp:
- 12/16/05 10:09:27 (7 years ago)
- Files:
-
- trunk/config/propel.ini (modified) (1 diff)
- trunk/config/properties.ini (modified) (1 diff)
- trunk/config/rsync_exclude.txt (modified) (1 diff)
- trunk/frontend/config/app.yml (modified) (1 diff)
- trunk/frontend/config/filters.yml (modified) (1 diff)
- trunk/frontend/lib/myTagFilter.class.php (added)
- trunk/frontend/modules/answer/templates/_answer.php (modified) (1 diff)
- trunk/frontend/modules/content/actions/actions.class.php (modified) (1 diff)
- trunk/frontend/modules/content/templates/aboutSuccess.php (modified) (1 diff)
- trunk/frontend/modules/feed/actions/actions.class.php (modified) (3 diffs)
- trunk/frontend/modules/question/actions/actions.class.php (modified) (1 diff)
- trunk/frontend/modules/tag/actions/actions.class.php (modified) (1 diff)
- trunk/frontend/templates/layout.php (modified) (1 diff)
- trunk/lib/model/AnswerPeer.php (modified) (3 diffs)
- trunk/lib/model/Question.php (modified) (4 diffs)
- trunk/lib/model/QuestionPeer.php (modified) (5 diffs)
- trunk/lib/model/QuestionTagPeer.php (modified) (3 diffs)
- trunk/lib/model/User.php (modified) (2 diffs)
- trunk/web/css/main.css (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/config/propel.ini
r4 r40 13 13 ; directories 14 14 propel.home = . 15 propel.output.dir = /home/production/askeet svn15 propel.output.dir = /home/production/askeet 16 16 propel.schema.dir = ${propel.output.dir}/config 17 17 propel.conf.dir = ${propel.output.dir}/config trunk/config/properties.ini
r2 r40 1 1 [symfony] 2 2 name=askeet 3 4 [production] 5 host=localhost 6 port=8042 7 user=root 8 dir=/home/production/askeet/ trunk/config/rsync_exclude.txt
r2 r40 4 4 cache 5 5 log 6 frontend/config/orm.yml 7 web/frontend_dev.php trunk/frontend/config/app.yml
r38 r40 2 2 all: 3 3 pager: 4 homepage_max: 55 answers_max: 56 users_max: 104 homepage_max: 5 5 answers_max: 5 6 users_max: 10 7 7 8 8 feed: 9 max_questions: 10 9 max_questions: 10 10 11 .global: 12 host_exclude_regex: /^(www|askeet)/ trunk/frontend/config/filters.yml
r2 r40 1 myTagFilter: 2 class: myTagFilter trunk/frontend/modules/answer/templates/_answer.php
r38 r40 7 7 <div class="answer_body"> 8 8 <?php echo $answer->getHtmlBody() ?> 9 <div class="subtitle" >answered by <?php echo link_to_profile($answer->getUser()) ?> on <?php echo format_date($answer->getCreatedAt(), 'f') ?></div>9 <div class="subtitle" style="margin-top: -8px">answered by <?php echo link_to_profile($answer->getUser()) ?> on <?php echo format_date($answer->getCreatedAt(), 'f') ?></div> 10 10 </div> 11 11 trunk/frontend/modules/content/actions/actions.class.php
r38 r40 13 13 public function executeAbout() 14 14 { 15 require_once('markdown.php'); 16 17 $this->html = markdown(file_get_contents(SF_DATA_DIR.'/content/about.txt')); 18 15 19 $this->setTitle('askeet! » about'); 16 20 } trunk/frontend/modules/content/templates/aboutSuccess.php
r38 r40 1 <h1>About askeet</h1> 2 3 <p>Askeet is a <strong>community based Q&A repository</strong>.</p> 4 5 <p>Anyone can post a question about any subject, or answer an existing question. 6 Registration and use are completely free. 7 If you need an answer, ask your question, register to its RSS feed of answers, and just wait 8 until your news aggregator pops out with an answer. 9 Questions and answers can be rated, so that the most interesting questions and the most 10 useful answers come first. If you have knowledge to share, pay askeet a visit from time to time, 11 you might even earn some money. 12 </p> 13 14 <p>Askeet is also an open-source software developed in PHP. 15 Download, adaptation and commercial distribution are free, according to the MIT license. 16 Easy to install and to customize, askeet may be the solution you are looking for if 17 you need a FAQ section on your Intranet, or for a mini knowledge base for your community. 18 </p> 19 20 <p>Askeet is also the result of a 24-days tutorial called 21 the <a href="http://www.symfony-project.com/askeet">symfony advent calendar</a>, and issued on December 2005 to 22 illustrate agile development of a web 2.0 application in PHP with 23 the <a href="http://www.symfony-project.com/">symfony framework</a>. Reading the tutorial will introduce you to 24 symfony and explain all the code behind the askeet application. 25 </p> 26 27 <p>Askeet is published by Sensio and the symfony development team.</p> 1 <?php echo $html ?> trunk/frontend/modules/feed/actions/actions.class.php
r27 r40 19 19 { 20 20 // questions 21 $c = new Criteria(); 22 $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS); 23 $c->setLimit(APP_FEED_MAX_QUESTIONS); 24 $questions = QuestionPeer::doSelectJoinUser($c); 21 $questions = QuestionPeer::getPopular(APP_FEED_MAX_QUESTIONS); 25 22 26 23 $feed = sfFeed::newInstance('rss201rev2'); … … 42 39 { 43 40 // questions 44 $c = new Criteria(); 45 $c->addDescendingOrderByColumn(QuestionPeer::CREATED_AT); 46 $c->setLimit(APP_FEED_MAX_QUESTIONS); 47 $questions = QuestionPeer::doSelectJoinUser($c); 41 $questions = QuestionPeer::getRecent(APP_FEED_MAX_QUESTIONS); 48 42 49 43 $feed = sfFeed::newInstance('rss201rev2'); … … 65 59 { 66 60 // questions 67 $c = new Criteria(); 68 $c->addDescendingOrderByColumn(AnswerPeer::CREATED_AT); 69 $c->setLimit(APP_FEED_MAX_QUESTIONS); 70 $answers = AnswerPeer::doSelectJoinUser($c); 61 $answers = AnswerPeer::getRecent(APP_FEED_MAX_QUESTIONS); 71 62 72 63 $feed = sfFeed::newInstance('rss201rev2'); trunk/frontend/modules/question/actions/actions.class.php
r38 r40 21 21 $this->forward404Unless($this->question); 22 22 23 $c = new Criteria(); 24 $c->add(AnswerPeer::QUESTION_ID, $this->question->getId()); 25 $c->addDescendingOrderByColumn(AnswerPeer::RELEVANCY_UP); 26 $this->answers = AnswerPeer::doSelect($c); 23 $this->answers = $this->question->getPopularAnswers(); 27 24 28 25 $this->setTitle('askeet! » '.$this->question->getTitle()); trunk/frontend/modules/tag/actions/actions.class.php
r38 r40 23 23 $this->getRequest()->setAttribute('disable_web_debug', true, 'debug/web'); 24 24 25 $tags = array(); 26 27 $con = Propel::getConnection(); 28 $query = ' 29 SELECT DISTINCT %s AS tag 30 FROM %s 31 WHERE %s = ? AND %s LIKE ? 32 ORDER BY %s 33 '; 34 35 $query = sprintf($query, 36 QuestionTagPeer::TAG, 37 QuestionTagPeer::TABLE_NAME, 38 QuestionTagPeer::USER_ID, 39 QuestionTagPeer::TAG, 40 QuestionTagPeer::TAG 41 ); 42 43 $stmt = $con->prepareStatement($query); 44 $stmt->setInt(1, $this->getUser()->getSubscriberId()); 45 $stmt->setString(2, $this->getRequestParameter('tag').'%'); 46 $stmt->setLimit(10); 47 $rs = $stmt->executeQuery(); 48 while ($rs->next()) 49 { 50 $tags[] = $rs->getString('tag'); 51 } 52 53 $this->tags = $tags; 25 $this->tags = QuestionTagPeer::getForUserLike($this->getUser()->getSubscriberId(), $this->getRequestParameter('tag')); 54 26 } 55 27 trunk/frontend/templates/layout.php
r38 r40 26 26 <div id="header"> 27 27 <ul> 28 <?php if ($user-> hasAttribute('nickname', 'subscriber')): ?>28 <?php if ($user->isAuthenticated()): ?> 29 29 <li><?php echo link_to('sign out', '@logout') ?></li> 30 30 <li><?php echo link_to($user->getAttribute('nickname', '', 'subscriber').' profile', '@current_user_profile') ?></li> trunk/lib/model/AnswerPeer.php
r18 r40 28 28 $c->addDescendingOrderByColumn(self::RELEVANCY_UP); 29 29 $c->addDescendingOrderByColumn(self::CREATED_AT); 30 $c = self::addPermanentTagToCriteria($c); 30 31 $pager->setCriteria($c); 31 32 $pager->setPage($page); … … 40 41 $c = new Criteria(); 41 42 $c->addDescendingOrderByColumn(self::CREATED_AT); 43 $c = self::addPermanentTagToCriteria($c); 42 44 $pager->setCriteria($c); 43 45 $pager->setPage($page); … … 47 49 return $pager; 48 50 } 51 52 public function getRecent($max = 10) 53 { 54 $c = new Criteria(); 55 $c->addDescendingOrderByColumn(self::CREATED_AT); 56 $c = self::addPermanentTagToCriteria($c); 57 $c->setLimit($max); 58 59 return self::doSelectJoinUser($c); 60 } 61 62 private static function addPermanentTagToCriteria($criteria) 63 { 64 if (defined('APP_PERMANENT_TAG')) 65 { 66 $criteria->addJoin(self::QUESTION_ID, QuestionTagPeer::QUESTION_ID, Criteria::LEFT_JOIN); 67 $criteria->add(QuestionTagPeer::NORMALIZED_TAG, APP_PERMANENT_TAG); 68 $criteria->setDistinct(); 69 } 70 71 return $criteria; 72 } 49 73 } 50 74 trunk/lib/model/Question.php
r34 r40 67 67 foreach (QuestionTagPeer::doSelect($c) as $tag) 68 68 { 69 if (defined('APP_PERMANENT_TAG') && APP_PERMANENT_TAG == $tag) 70 { 71 continue; 72 } 73 69 74 $tags[] = $tag->getNormalizedTag(); 70 75 } … … 100 105 while ($rs->next()) 101 106 { 107 if (defined('APP_PERMANENT_TAG') && APP_PERMANENT_TAG == $rs->getString('tag')) 108 { 109 continue; 110 } 111 102 112 $tags[$rs->getString('tag')] = $rs->getInt('count'); 103 113 } … … 109 119 { 110 120 // split phrase into individual tags 111 $tags = Tag::splitPhrase($phrase );121 $tags = Tag::splitPhrase($phrase.(defined('APP_PERMANENT_TAG') ? ' '.APP_PERMANENT_TAG : '')); 112 122 113 123 // add tags … … 121 131 } 122 132 } 133 134 public function getPopularAnswers() 135 { 136 $c = new Criteria(); 137 $c->add(AnswerPeer::QUESTION_ID, $this->getId()); 138 $c->addAsColumn('relevancy', AnswerPeer::RELEVANCY_UP.' / ('.AnswerPeer::RELEVANCY_UP.' + '.AnswerPeer::RELEVANCY_DOWN.')'); 139 $c->addDescendingOrderByColumn('relevancy'); 140 141 return AnswerPeer::doSelect($c); 142 } 123 143 } 124 144 trunk/lib/model/QuestionPeer.php
r38 r40 36 36 $c = new Criteria(); 37 37 $c->addDescendingOrderByColumn(self::INTERESTED_USERS); 38 /* 39 if (1) 40 { 41 $c->addJoin(self::ID, QuestionTagPeer::QUESTION_ID, Criteria::LEFT_JOIN); 42 $c->add(QuestionTagPeer::NORMALIZED_TAG, 'perl'); 43 $c->setDistinct(); 44 } 45 */ 38 $c = self::addPermanentTagToCriteria($c); 46 39 $pager->setCriteria($c); 47 40 $pager->setPage($page); … … 52 45 } 53 46 47 public function getPopular($max = 10) 48 { 49 $c = new Criteria(); 50 $c->addDescendingOrderByColumn(self::INTERESTED_USERS); 51 $c = self::addPermanentTagToCriteria($c); 52 $c->setLimit($max); 53 54 return self::doSelectJoinUser($c); 55 } 56 54 57 public static function getRecentPager($page) 55 58 { … … 57 60 $c = new Criteria(); 58 61 $c->addDescendingOrderByColumn(self::CREATED_AT); 62 $c = self::addPermanentTagToCriteria($c); 59 63 $pager->setCriteria($c); 60 64 $pager->setPage($page); … … 65 69 } 66 70 71 public function getRecent($max = 10) 72 { 73 $c = new Criteria(); 74 $c->addDescendingOrderByColumn(self::CREATED_AT); 75 $c = self::addPermanentTagToCriteria($c); 76 $c->setLimit($max); 77 78 return self::doSelectJoinUser($c); 79 } 80 67 81 public static function getPopularByTag($tag, $page) 68 82 { 69 83 $c = new Criteria(); 70 $c->add(QuestionTagPeer::NORMALIZED_TAG, $tag);71 84 $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS); 72 $c->addJoin(QuestionTagPeer::QUESTION_ID, QuestionPeer::ID, Criteria::LEFT_JOIN); 85 86 // tags 87 $c->addJoin(self::ID, QuestionTagPeer::QUESTION_ID, Criteria::LEFT_JOIN); 88 $criterion = $c->getNewCriterion(QuestionTagPeer::NORMALIZED_TAG, $tag); 89 if (defined('APP_PERMANENT_TAG')) 90 { 91 $criterion->addAnd($c->getNewCriterion(QuestionTagPeer::NORMALIZED_TAG, APP_PERMANENT_TAG)); 92 } 93 $c->add($criterion); 94 $c->setDistinct(); 73 95 74 96 $pager = new sfPager('Question', 20); … … 79 101 return $pager; 80 102 } 103 104 private static function addPermanentTagToCriteria($criteria) 105 { 106 if (defined('APP_PERMANENT_TAG')) 107 { 108 $criteria->addJoin(self::ID, QuestionTagPeer::QUESTION_ID, Criteria::LEFT_JOIN); 109 $criteria->add(QuestionTagPeer::NORMALIZED_TAG, APP_PERMANENT_TAG); 110 $criteria->setDistinct(); 111 } 112 113 return $criteria; 114 } 81 115 } 82 116 trunk/lib/model/QuestionTagPeer.php
r38 r40 27 27 $con = Propel::getConnection(); 28 28 $query = ' 29 SELECT '.QuestionTagPeer::NORMALIZED_TAG.'AS tag,30 COUNT( '.QuestionTagPeer::NORMALIZED_TAG.') AS count31 FROM '.QuestionTagPeer::TABLE_NAME ;29 SELECT t1.normalized_tag AS tag, 30 COUNT(t1.normalized_tag) AS count 31 FROM '.QuestionTagPeer::TABLE_NAME.' AS t1'; 32 32 33 if ( 1)33 if (defined('APP_PERMANENT_TAG')) 34 34 { 35 /*36 35 $query .= ' 37 LEFT JOIN '.QuestionPeer::TABLE_NAME.'38 GROUP BY '.QuestionTagPeer::NORMALIZED_TAG;39 */ 36 INNER JOIN '.QuestionTagPeer::TABLE_NAME.' AS t2 ON t1.question_id = t2.question_id 37 WHERE t2.normalized_tag = ? AND t1.normalized_tag != ? 38 '; 40 39 } 41 40 42 41 $query .= ' 43 GROUP BY '.QuestionTagPeer::NORMALIZED_TAG.' 44 ORDER BY count DESC'; 42 GROUP BY t1.normalized_tag 43 ORDER BY count DESC 44 '; 45 45 46 46 $stmt = $con->prepareStatement($query); 47 if (defined('APP_PERMANENT_TAG')) 48 { 49 $stmt->setString(1, APP_PERMANENT_TAG); 50 $stmt->setString(2, APP_PERMANENT_TAG); 51 } 47 52 $stmt->setLimit($max); 48 53 $rs = $stmt->executeQuery(); … … 92 97 while ($rs->next()) 93 98 { 99 if (defined('APP_PERMANENT_TAG') && APP_PERMANENT_TAG == $rs->getString('tag')) 100 { 101 continue; 102 } 103 94 104 if (!$max_popularity) 95 105 { … … 104 114 return $tags; 105 115 } 116 117 public static function getForUserLike($user_id, $tag) 118 { 119 $tags = array(); 120 121 $con = Propel::getConnection(); 122 $query = ' 123 SELECT DISTINCT %s AS tag 124 FROM %s 125 WHERE %s = ? AND %s LIKE ? 126 ORDER BY %s 127 '; 128 129 $query = sprintf($query, 130 QuestionTagPeer::TAG, 131 QuestionTagPeer::TABLE_NAME, 132 QuestionTagPeer::USER_ID, 133 QuestionTagPeer::TAG, 134 QuestionTagPeer::TAG 135 ); 136 137 $stmt = $con->prepareStatement($query); 138 $stmt->setInt(1, $user_id); 139 $stmt->setString(2, $tag.'%'); 140 $stmt->setLimit(10); 141 $rs = $stmt->executeQuery(); 142 while ($rs->next()) 143 { 144 $tags[] = $rs->getString('tag'); 145 } 146 147 return $tags; 148 } 106 149 } 107 150 trunk/lib/model/User.php
r38 r40 74 74 while ($rs->next()) 75 75 { 76 if (defined('APP_PERMANENT_TAG') && APP_PERMANENT_TAG == $rs->getString('tag')) 77 { 78 continue; 79 } 80 76 81 $tags[$rs->getString('tag')] = $rs->getString('raw_tag'); 77 82 } … … 112 117 while ($rs->next()) 113 118 { 119 if (defined('APP_PERMANENT_TAG') && APP_PERMANENT_TAG == $rs->getString('tag')) 120 { 121 continue; 122 } 123 114 124 if (!$max_popularity) 115 125 { trunk/web/css/main.css
r38 r40 41 41 div#header h1 42 42 { 43 padding: 30px;43 padding: 30px; 44 44 font-family: Verdana, sans-serif; 45 45 font-size: 17px; 46 46 font-weight: bold; 47 47 color: #c8c8c8; 48 letter-spacing: -1px; 48 49 } 49 50
