Changeset 31
- Timestamp:
- 12/12/05 19:54:21 (7 years ago)
- Files:
-
- trunk/config/schema.xml (modified) (1 diff)
- trunk/data/fixtures/test_data.yml (modified) (1 diff)
- trunk/frontend/config/routing.yml (modified) (1 diff)
- trunk/frontend/lib/helper/QuestionHelper.php (modified) (1 diff)
- trunk/frontend/modules/question/config/view.yml (added)
- trunk/frontend/modules/question/templates/_question_list.php (modified) (2 diffs)
- trunk/frontend/modules/sidebar/actions/actions.class.php (modified) (1 diff)
- trunk/frontend/modules/sidebar/templates/questionSuccess.php (added)
- trunk/frontend/modules/tag (added)
- trunk/frontend/modules/tag/actions (added)
- trunk/frontend/modules/tag/actions/actions.class.php (added)
- trunk/frontend/modules/tag/config (added)
- trunk/frontend/modules/tag/config/.sf (added)
- trunk/frontend/modules/tag/lib (added)
- trunk/frontend/modules/tag/lib/.sf (added)
- trunk/frontend/modules/tag/templates (added)
- trunk/frontend/modules/tag/templates/_question_tags.php (added)
- trunk/frontend/modules/tag/templates/showSuccess.php (added)
- trunk/frontend/modules/tag/validate (added)
- trunk/frontend/modules/tag/validate/.sf (added)
- trunk/lib/Tag.class.php (added)
- trunk/lib/model/Question.php (modified) (1 diff)
- trunk/lib/model/QuestionPeer.php (modified) (1 diff)
- trunk/lib/model/QuestionTag.php (added)
- trunk/lib/model/QuestionTagPeer.php (added)
- trunk/lib/model/map/QuestionTagMapBuilder.php (added)
- trunk/lib/model/om/BaseQuestion.php (modified) (5 diffs)
- trunk/lib/model/om/BaseQuestionTag.php (added)
- trunk/lib/model/om/BaseQuestionTagPeer.php (added)
- trunk/lib/model/om/BaseUser.php (modified) (5 diffs)
- trunk/test/frontend/tagActionsTest.php (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/config/schema.xml
r23 r31 69 69 </table> 70 70 71 <table name="ask_question_tag" phpName="QuestionTag"> 72 <column name="question_id" type="integer" /> 73 <foreign-key foreignTable="ask_question"> 74 <reference local="question_id" foreign="id" /> 75 </foreign-key> 76 <column name="user_id" type="integer" /> 77 <foreign-key foreignTable="ask_user"> 78 <reference local="user_id" foreign="id" /> 79 </foreign-key> 80 <column name="created_at" type="timestamp" /> 81 <column name="tag" type="varchar" size="100" /> 82 <column name="normalized_tag" type="varchar" size="100" /> 83 <index name="normalized_tag_index"> 84 <index-column name="normalized_tag" /> 85 </index> 86 </table> 87 71 88 </database> trunk/data/fixtures/test_data.yml
r23 r31 91 91 user_id: francois 92 92 score: -1 93 94 QuestionTag: 95 t1: { question_id: q1, user_id: fabien, tag: relatives } 96 t2: { question_id: q1, user_id: fabien, tag: girl } 97 t4: { question_id: q1, user_id: francois, tag: activities } 98 t6: { question_id: q2, user_id: francois, tag: 'real life' } 99 t5: { question_id: q2, user_id: fabien, tag: relatives } 100 t5: { question_id: q2, user_id: fabien, tag: present } 101 t6: { question_id: q2, user_id: francois, tag: 'real life' } 102 t7: { question_id: q3, user_id: francois, tag: blog } 103 t8: { question_id: q3, user_id: francois, tag: activities } trunk/frontend/config/routing.yml
r29 r31 59 59 param: { module: user, action: logout } 60 60 61 # tag 62 tag: 63 url: /tag/:tag 64 param: { module: tag, action: show } 65 61 66 # feeds 62 67 feed_recent_answers: trunk/frontend/lib/helper/QuestionHelper.php
r23 r31 1 1 <?php 2 2 3 function tags_for_question($question, $max = 5) 4 { 5 $tags = array(); 6 7 foreach ($question->getPopularTags($max) as $tag => $count) 8 { 9 $tags[] = link_to($tag, '@tag?tag='.$tag); 10 } 11 12 return implode(' + ', $tags); 13 } 14 3 15 ?> trunk/frontend/modules/question/templates/_question_list.php
r23 r31 1 <?php use_helpers('Text', 'Global' ) ?>1 <?php use_helpers('Text', 'Global', 'Question') ?> 2 2 3 3 <?php foreach($question_pager->getResults() as $question): ?> 4 4 <div class="interested_block" id="block_<?php echo $question->getId() ?>"> 5 <?php echo include_partial(' interested_user', array('question' => $question)) ?>5 <?php echo include_partial('question/interested_user', array('question' => $question)) ?> 6 6 </div> 7 7 … … 11 11 <?php echo truncate_text(strip_tags($question->getHtmlBody()), 200) ?> 12 12 </div> 13 tags: <?php echo tags_for_question($question) ?> 13 14 <?php endforeach ?> 14 15 trunk/frontend/modules/sidebar/actions/actions.class.php
r18 r31 14 14 { 15 15 } 16 17 public function executeQuestion() 18 { 19 $this->question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title')); 20 } 16 21 } 17 22 trunk/lib/model/Question.php
r23 r31 55 55 return $pager; 56 56 } 57 58 public function getTags() 59 { 60 $c = new Criteria(); 61 $c->add(QuestionTagPeer::QUESTION_ID, $this->getId()); 62 $c->addGroupByColumn(QuestionTagPeer::NORMALIZED_TAG); 63 $c->setDistinct(); 64 $c->addAscendingOrderByColumn(QuestionTagPeer::NORMALIZED_TAG); 65 66 $tags = array(); 67 foreach (QuestionTagPeer::doSelect($c) as $tag) 68 { 69 $tags[] = $tag->getNormalizedTag(); 70 } 71 72 return $tags; 73 } 74 75 public function getPopularTags($max = 5) 76 { 77 $tags = array(); 78 79 $con = Propel::getConnection(); 80 $query = ' 81 SELECT %s AS tag, COUNT(%s) AS count 82 FROM %s 83 WHERE %s = ? 84 GROUP BY %s 85 ORDER BY count DESC 86 '; 87 88 $query = sprintf($query, 89 QuestionTagPeer::NORMALIZED_TAG, 90 QuestionTagPeer::NORMALIZED_TAG, 91 QuestionTagPeer::TABLE_NAME, 92 QuestionTagPeer::QUESTION_ID, 93 QuestionTagPeer::NORMALIZED_TAG 94 ); 95 96 $stmt = $con->prepareStatement($query); 97 $stmt->setInt(1, $this->getId()); 98 $stmt->setLimit($max); 99 $rs = $stmt->executeQuery(); 100 while ($rs->next()) 101 { 102 $tags[$rs->getString('tag')] = $rs->getInt('count'); 103 } 104 105 return $tags; 106 } 57 107 } 58 108 trunk/lib/model/QuestionPeer.php
r18 r31 56 56 return $pager; 57 57 } 58 59 public static function getPopularByTag($tag, $page) 60 { 61 $c = new Criteria(); 62 $c->add(QuestionTagPeer::NORMALIZED_TAG, $tag); 63 $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS); 64 $c->addJoin(QuestionTagPeer::QUESTION_ID, QuestionPeer::ID, Criteria::LEFT_JOIN); 65 66 $pager = new sfPager('Question', 20); 67 $pager->setCriteria($c); 68 $pager->setPage($page); 69 $pager->init(); 70 71 return $pager; 72 } 58 73 } 59 74 trunk/lib/model/om/BaseQuestion.php
r23 r31 119 119 */ 120 120 private $lastInterestCriteria = null; 121 122 /** 123 * Collection to store aggregation of collQuestionTags. 124 * @var array 125 */ 126 protected $collQuestionTags; 127 128 /** 129 * The criteria used to select the current contents of collQuestionTags. 130 * @var Criteria 131 */ 132 private $lastQuestionTagCriteria = null; 121 133 122 134 /** … … 615 627 } 616 628 629 if ($this->collQuestionTags !== null) { 630 foreach($this->collQuestionTags as $referrerFK) { 631 if (!$referrerFK->isDeleted()) { 632 $affectedRows += $referrerFK->save($con); 633 } 634 } 635 } 636 617 637 $this->alreadyInSave = false; 618 638 } … … 685 705 if ($this->collInterests !== null) { 686 706 foreach($this->collInterests as $referrerFK) { 707 if (($retval = $referrerFK->validate()) !== true) { 708 $failureMap = array_merge($failureMap, $retval); 709 } 710 } 711 } 712 713 if ($this->collQuestionTags !== null) { 714 foreach($this->collQuestionTags as $referrerFK) { 687 715 if (($retval = $referrerFK->validate()) !== true) { 688 716 $failureMap = array_merge($failureMap, $retval); … … 975 1003 } 976 1004 1005 foreach($this->getQuestionTags() as $relObj) { 1006 $copyObj->addQuestionTag($relObj->copy($deepCopy)); 1007 } 1008 977 1009 } // if ($deepCopy) 978 1010 … … 1383 1415 } 1384 1416 1417 /** 1418 * Temporary storage of collQuestionTags to save a possible db hit in 1419 * the event objects are add to the collection, but the 1420 * complete collection is never requested. 1421 * @return void 1422 */ 1423 public function initQuestionTags() 1424 { 1425 if ($this->collQuestionTags === null) { 1426 $this->collQuestionTags = array(); 1427 } 1428 } 1429 1430 /** 1431 * If this collection has already been initialized with 1432 * an identical criteria, it returns the collection. 1433 * Otherwise if this Question has previously 1434 * been saved, it will retrieve related QuestionTags from storage. 1435 * If this Question is new, it will return 1436 * an empty collection or the current collection, the criteria 1437 * is ignored on a new object. 1438 * 1439 * @param Connection $con 1440 * @param Criteria $criteria 1441 * @throws PropelException 1442 */ 1443 public function getQuestionTags($criteria = null, $con = null) 1444 { 1445 // include the Peer class 1446 include_once 'model/om/BaseQuestionTagPeer.php'; 1447 if ($criteria === null) { 1448 $criteria = new Criteria(); 1449 } 1450 elseif ($criteria instanceof Criteria) 1451 { 1452 $criteria = clone $criteria; 1453 } 1454 1455 if ($this->collQuestionTags === null) { 1456 if ($this->isNew()) { 1457 $this->collQuestionTags = array(); 1458 } else { 1459 1460 $criteria->add(QuestionTagPeer::QUESTION_ID, $this->getId()); 1461 1462 QuestionTagPeer::addSelectColumns($criteria); 1463 $this->collQuestionTags = QuestionTagPeer::doSelect($criteria, $con); 1464 } 1465 } else { 1466 // criteria has no effect for a new object 1467 if (!$this->isNew()) { 1468 // the following code is to determine if a new query is 1469 // called for. If the criteria is the same as the last 1470 // one, just return the collection. 1471 1472 1473 $criteria->add(QuestionTagPeer::QUESTION_ID, $this->getId()); 1474 1475 QuestionTagPeer::addSelectColumns($criteria); 1476 if (!isset($this->lastQuestionTagCriteria) || !$this->lastQuestionTagCriteria->equals($criteria)) { 1477 $this->collQuestionTags = QuestionTagPeer::doSelect($criteria, $con); 1478 } 1479 } 1480 } 1481 $this->lastQuestionTagCriteria = $criteria; 1482 return $this->collQuestionTags; 1483 } 1484 1485 /** 1486 * Returns the number of related QuestionTags. 1487 * 1488 * @param Criteria $criteria 1489 * @param Connection $con 1490 * @throws PropelException 1491 */ 1492 public function countQuestionTags($criteria = null, $con = null) 1493 { 1494 // include the Peer class 1495 include_once 'model/om/BaseQuestionTagPeer.php'; 1496 if ($criteria === null) { 1497 $criteria = new Criteria(); 1498 } 1499 elseif ($criteria instanceof Criteria) 1500 { 1501 $criteria = clone $criteria; 1502 } 1503 1504 $criteria->add(QuestionTagPeer::QUESTION_ID, $this->getId()); 1505 1506 return QuestionTagPeer::doCount($criteria, $con); 1507 } 1508 1509 /** 1510 * Method called to associate a QuestionTag object to this object 1511 * through the QuestionTag foreign key attribute 1512 * 1513 * @param QuestionTag $l QuestionTag 1514 * @return void 1515 * @throws PropelException 1516 */ 1517 public function addQuestionTag(QuestionTag $l) 1518 { 1519 $this->collQuestionTags[] = $l; 1520 $l->setQuestion($this); 1521 } 1522 1523 1524 /** 1525 * If this collection has already been initialized with 1526 * an identical criteria, it returns the collection. 1527 * Otherwise if this Question is new, it will return 1528 * an empty collection; or if this Question has previously 1529 * been saved, it will retrieve related QuestionTags from storage. 1530 * 1531 * This method is protected by default in order to keep the public 1532 * api reasonable. You can provide public methods for those you 1533 * actually need in Question. 1534 */ 1535 public function getQuestionTagsJoinUser($criteria = null, $con = null) 1536 { 1537 // include the Peer class 1538 include_once 'model/om/BaseQuestionTagPeer.php'; 1539 if ($criteria === null) { 1540 $criteria = new Criteria(); 1541 } 1542 elseif ($criteria instanceof Criteria) 1543 { 1544 $criteria = clone $criteria; 1545 } 1546 1547 if ($this->collQuestionTags === null) { 1548 if ($this->isNew()) { 1549 $this->collQuestionTags = array(); 1550 } else { 1551 1552 $criteria->add(QuestionTagPeer::QUESTION_ID, $this->getId()); 1553 1554 $this->collQuestionTags = QuestionTagPeer::doSelectJoinUser($criteria, $con); 1555 } 1556 } else { 1557 // the following code is to determine if a new query is 1558 // called for. If the criteria is the same as the last 1559 // one, just return the collection. 1560 1561 $criteria->add(QuestionTagPeer::QUESTION_ID, $this->getId()); 1562 1563 if (!isset($this->lastQuestionTagCriteria) || !$this->lastQuestionTagCriteria->equals($criteria)) { 1564 $this->collQuestionTags = QuestionTagPeer::doSelectJoinUser($criteria, $con); 1565 } 1566 } 1567 $this->lastQuestionTagCriteria = $criteria; 1568 1569 return $this->collQuestionTags; 1570 } 1571 1385 1572 } // BaseQuestion trunk/lib/model/om/BaseUser.php
r16 r31 131 131 */ 132 132 private $lastRelevancyCriteria = null; 133 134 /** 135 * Collection to store aggregation of collQuestionTags. 136 * @var array 137 */ 138 protected $collQuestionTags; 139 140 /** 141 * The criteria used to select the current contents of collQuestionTags. 142 * @var Criteria 143 */ 144 private $lastQuestionTagCriteria = null; 133 145 134 146 /** … … 568 580 } 569 581 582 if ($this->collQuestionTags !== null) { 583 foreach($this->collQuestionTags as $referrerFK) { 584 if (!$referrerFK->isDeleted()) { 585 $affectedRows += $referrerFK->save($con); 586 } 587 } 588 } 589 570 590 $this->alreadyInSave = false; 571 591 } … … 642 662 if ($this->collRelevancys !== null) { 643 663 foreach($this->collRelevancys as $referrerFK) { 664 if (($retval = $referrerFK->validate()) !== true) { 665 $failureMap = array_merge($failureMap, $retval); 666 } 667 } 668 } 669 670 if ($this->collQuestionTags !== null) { 671 foreach($this->collQuestionTags as $referrerFK) { 644 672 if (($retval = $referrerFK->validate()) !== true) { 645 673 $failureMap = array_merge($failureMap, $retval); … … 929 957 } 930 958 959 foreach($this->getQuestionTags() as $relObj) { 960 $copyObj->addQuestionTag($relObj->copy($deepCopy)); 961 } 962 931 963 } // if ($deepCopy) 932 964 … … 1547 1579 } 1548 1580 1581 /** 1582 * Temporary storage of collQuestionTags to save a possible db hit in 1583 * the event objects are add to the collection, but the 1584 * complete collection is never requested. 1585 * @return void 1586 */ 1587 public function initQuestionTags() 1588 { 1589 if ($this->collQuestionTags === null) { 1590 $this->collQuestionTags = array(); 1591 } 1592 } 1593 1594 /** 1595 * If this collection has already been initialized with 1596 * an identical criteria, it returns the collection. 1597 * Otherwise if this User has previously 1598 * been saved, it will retrieve related QuestionTags from storage. 1599 * If this User is new, it will return 1600 * an empty collection or the current collection, the criteria 1601 * is ignored on a new object. 1602 * 1603 * @param Connection $con 1604 * @param Criteria $criteria 1605 * @throws PropelException 1606 */ 1607 public function getQuestionTags($criteria = null, $con = null) 1608 { 1609 // include the Peer class 1610 include_once 'model/om/BaseQuestionTagPeer.php'; 1611 if ($criteria === null) { 1612 $criteria = new Criteria(); 1613 } 1614 elseif ($criteria instanceof Criteria) 1615 { 1616 $criteria = clone $criteria; 1617 } 1618 1619 if ($this->collQuestionTags === null) { 1620 if ($this->isNew()) { 1621 $this->collQuestionTags = array(); 1622 } else { 1623 1624 $criteria->add(QuestionTagPeer::USER_ID, $this->getId()); 1625 1626 QuestionTagPeer::addSelectColumns($criteria); 1627 $this->collQuestionTags = QuestionTagPeer::doSelect($criteria, $con); 1628 } 1629 } else { 1630 // criteria has no effect for a new object 1631 if (!$this->isNew()) { 1632 // the following code is to determine if a new query is 1633 // called for. If the criteria is the same as the last 1634 // one, just return the collection. 1635 1636 1637 $criteria->add(QuestionTagPeer::USER_ID, $this->getId()); 1638 1639 QuestionTagPeer::addSelectColumns($criteria); 1640 if (!isset($this->lastQuestionTagCriteria) || !$this->lastQuestionTagCriteria->equals($criteria)) { 1641 $this->collQuestionTags = QuestionTagPeer::doSelect($criteria, $con); 1642 } 1643 } 1644 } 1645 $this->lastQuestionTagCriteria = $criteria; 1646 return $this->collQuestionTags; 1647 } 1648 1649 /** 1650 * Returns the number of related QuestionTags. 1651 * 1652 * @param Criteria $criteria 1653 * @param Connection $con 1654 * @throws PropelException 1655 */ 1656 public function countQuestionTags($criteria = null, $con = null) 1657 { 1658 // include the Peer class 1659 include_once 'model/om/BaseQuestionTagPeer.php'; 1660 if ($criteria === null) { 1661 $criteria = new Criteria(); 1662 } 1663 elseif ($criteria instanceof Criteria) 1664 { 1665 $criteria = clone $criteria; 1666 } 1667 1668 $criteria->add(QuestionTagPeer::USER_ID, $this->getId()); 1669 1670 return QuestionTagPeer::doCount($criteria, $con); 1671 } 1672 1673 /** 1674 * Method called to associate a QuestionTag object to this object 1675 * through the QuestionTag foreign key attribute 1676 * 1677 * @param QuestionTag $l QuestionTag 1678 * @return void 1679 * @throws PropelException 1680 */ 1681 public function addQuestionTag(QuestionTag $l) 1682 { 1683 $this->collQuestionTags[] = $l; 1684 $l->setUser($this); 1685 } 1686 1687 1688 /** 1689 * If this collection has already been initialized with 1690 * an identical criteria, it returns the collection. 1691 * Otherwise if this User is new, it will return 1692 * an empty collection; or if this User has previously 1693 * been saved, it will retrieve related QuestionTags from storage. 1694 * 1695 * This method is protected by default in order to keep the public 1696 * api reasonable. You can provide public methods for those you 1697 * actually need in User. 1698 */ 1699 public function getQuestionTagsJoinQuestion($criteria = null, $con = null) 1700 { 1701 // include the Peer class 1702 include_once 'model/om/BaseQuestionTagPeer.php'; 1703 if ($criteria === null) { 1704 $criteria = new Criteria(); 1705 } 1706 elseif ($criteria instanceof Criteria) 1707 { 1708 $criteria = clone $criteria; 1709 } 1710 1711 if ($this->collQuestionTags === null) { 1712 if ($this->isNew()) { 1713 $this->collQuestionTags = array(); 1714 } else { 1715 1716 $criteria->add(QuestionTagPeer::USER_ID, $this->getId()); 1717 1718 $this->collQuestionTags = QuestionTagPeer::doSelectJoinQuestion($criteria, $con); 1719 } 1720 } else { 1721 // the following code is to determine if a new query is 1722 // called for. If the criteria is the same as the last 1723 // one, just return the collection. 1724 1725 $criteria->add(QuestionTagPeer::USER_ID, $this->getId()); 1726 1727 if (!isset($this->lastQuestionTagCriteria) || !$this->lastQuestionTagCriteria->equals($criteria)) { 1728 $this->collQuestionTags = QuestionTagPeer::doSelectJoinQuestion($criteria, $con); 1729 } 1730 } 1731 $this->lastQuestionTagCriteria = $criteria; 1732 1733 return $this->collQuestionTags; 1734 } 1735 1549 1736 } // BaseUser
