ZendChina | Zend中文权威资讯's Archiver

ZendChina 发表于 2007-12-29 23:25

Zend Framework 提示信息(二)

       ZendChina官方:上接[url=http://bbs.zendchina.net/thread-93-1-1.html]Zend Framework 提示信息(一)[/url]

[b]viewFeeds 视图[/b]
       这是 IndexController 为已登录的用户提供的主视图。该视图展示了可用行为及链接,以查看可用提要的摘要。定义这个文件,并将其放至视图目录中,如下图所示。

清单 12. 主 viewFeeds 视图                  
[php]<html>
<head>
    <title>You're Logged In!</title>
</head>
<body>
  [<a href="user/logout">Logout</a>]<br>
  [<a href="user/displayProfile">View/Update
profile</a>]<br>
  [<a href="feed">Sub/Unsubscribe to/from
Feeds</a>]<br>
  [<a href="feed/viewSavedEntries">View Saved
Entries</a>]<br>
  <h1>CHOMP! The Feed Reader</h1>
  <h3>Hello <?php echo $this->escape($this->username); ?>
      you're logged in!</h3>
...
  </table>
</body>
</html>
[/php]

       这里有四个可用行为:退出系统、查看/更新配置文件、订阅或退订以及查看已保存条目(参见图 1)。

图 1. 查看 viewFeeds 视图
[attach]118[/attach]

[b]FeedController [/b]
       FeedController 具有与提要相关的几个行为。单击 “Sub/Unsubscribe to/from Feeds” 这一链接,将调用 FeedController 的 indexAction 方法。定义 FeedController.php 文件,并将其放至控制器目录中,如下所示。

清单 13. FeedController
[php]                  
<?php
class FeedController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('feeds', '*');
        $select->where("feedname NOT IN " .
                       "(select feedname from subscribedfeeds ".
                       "        where username=?)",
                       $username);
        $sql = $select->__toString();
        $subFeeds = $db->fetchAll($select);
        $select = $db->select();
        $select->from('subscribedfeeds', '*');
        $select->where("username=?", $username);
        $sql = $select->__toString();
        $unsubFeeds = $db->fetchAll($sql);
        
        $view = Zend::registry('view');
        $view->title = 'View Available Feeds';
        $view->subFeeds = $subFeeds;
        $view->unsubFeeds = $unsubFeeds;
        echo $view->render('feeds.php');
    }
    public function noRouteAction()
    {
        $this->_redirect('/');
    }
}
?>
[/php]

       该代码先从注册库中存储的 fSession 对象中检索 username,然后检索两个提要列表:一个是当前用户已订阅的提要,一个是未订阅的。对数据库的第一次查询检索已订阅提要,将它们存储在 subFeeds 中,下一次查询检索了当前尚未订阅的提要并将其存储在 unsubFeeds 中。随后,从注册库中获得该视图,并将其初始化、呈现及显示出来。

[b]提要视图[/b]
       清单 13 呈现的视图是 feeds.php。此视图显示了已订阅提要和退订链接,以及未订阅提要清单同订阅链接。定义 feeds.php 文件,如下所示。

清单 14. 定义提要视图
[php]                  
<html>
<head>
    <title><?php echo $this->escape($this->title);
?></title>
</head>
<body>
  [<a href='/'>Back to Main Menu</a>]<br>
  <h1><?php echo $this->escape($this->title);
?></h1>
  
  <table>
    <tr>
      <td>Feed Title
              </td>
      <td>Subscribe to Feed</td>
    </tr>
  <?php
     foreach($this->subFeeds as $row){
         $entryTitle = $row['feedname'];
         echo "<tr><td>$entryTitle</td>";
         echo "<td><a
href='feed/subscribe?title=$entryTitle'>".
              "subscribe</a></td></tr>";
     }
?>
    <tr><tr><td> </td></tr>
      <td>Feed Title
              </td>
      <td>Unsubscribe to Feed</td>
    </tr>
  <?php
     foreach($this->unsubFeeds as $row){
         $entryTitle = $row['feedname'];
         echo "<tr><td>$entryTitle</td>";
         echo "<td><a
href='feed/unsubscribe?title=$entryTitle'>".
              "unsubscribe</a></td></tr>";
     }
?>
  </table>
</body>
</html>
[/php]

       首先显示一些标题信息,随后遍历 subFeeds 对象中的每一个条目,并同退订链接一起显示出来。请注意该链接是提要/订阅,也就是说,单击该链接时,FeedController 对象的 subscribeAction 方法将被调用。对于退订提要的列表也采用相同的处理方法,不同之处只是调用 unsubscribeAction 方法。关于清单 14 视图的浏览器输出,请参见图 2。

图 2. 提要视图
[attach]119[/attach]

       接下来定义 subscribeAction 方法,然后再定义 unsubscribeAction 方法。

[b]订阅提要[/b]
       用户想要订阅提要时,subscribeAction 将被调用。必要的行为就是向数据库添加提要链接以及订阅该提要的用户名。在 FeedController 类中定义 subscribeAction,如下所示。

清单 15. 定义 subscribeAction 方法
[php]                  
    public function subscribeAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('title');
        $db = Zend::registry('db');
        $row = array(
                     'Username' => $username,
                     'feedname' => $feedTitle
                     );
            
        $table = 'subscribedfeeds';
        $rowsAffected = $db->insert($table, $row);
        $this->_redirect('/feed');
    }
[/php]

       此方法从 Zend 注册库的 fSession 和 fGet 对象中分别检索 username 和 feedTitle。随后准备了一条 SQL 语句,用于向 subscribedfeeds 表中插入一行,以使用户订阅到所需提要。图 3 是订阅了 Yahoo News 后的浏览器的例子。

图 3. 订阅 Yahoo News
[attach]120[/attach]

[b]退订提要[/b]
       退订提要与订阅提要正好相反。定义 FeedController 的 unsubscribeAction 方法,如下所示。

清单 16. 定义 unsubscribeAction 方法
[php]                  
    public function unsubscribeAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('title');
        $db = Zend::registry('db');
        $table = 'subscribedfeeds';
        $where = "username='$username' and feedname='$feedTitle'";
        $rowsAffected = $db->delete($table, $where);
        $this->_redirect('/feed');
    }
[/php]

       在这里,从 Zend 注册库的 fSession 和 fGet 对象中分别检索了 username 和 feedTitle,这与订阅提要时一样。然后准备了一条 SQL 语句用于删除 subscribedfeeds 表中与给出的 username 和 feedTitle 相匹配的记录。 在下一部分中,将提到浏览这些可用提要。退订 Yahoo News 会使您返回图 3。

[b]查看可用提要[/b]
       既然用户已经能够订阅提要了,那么他们就应该能够查看已订阅的提要以及每个提要中的摘要。本部分完成了 viewFeeds 视图、查看提要的摘要和 viewChannel 视图。

[b]完成 viewFeeds 视图[/b]
       在清单 12 中,开始实现 viewFeeds 视图,现在我们继续完成它,使您能够查看当前可用的提要。完成对 viewFeeds.php 文件的定义,如下所示。

清单 17. 完成 viewFeeds 视图
[php]                  
<html>
<head>
    <title>You're Logged In!</title>
</head>
<body>
...
  <h3>Hello <?php echo $this->escape($this->username); ?>
      you're logged in!</h3>
  Subscribed Feeds:<br>
  <?php
     $ct = 0;
     $feeds = $this->feeds;
     foreach($feeds as $row){
         $feedTitle = $row['feedname'];
         echo "<a href='feed/viewChannel?title=$feedTitle'>".
              "$feedTitle</a><br>";
     }
     ?>
  </table>
</body>
</html>
[/php]

       这里遍历了可用提要,显示出标题并添加了一个查看最新摘要的链接。请注意该行为的名称是 FeedController 类中的 viewChannel 行为。已完成的 viewFeeds 视图浏览器输出如图 4 所示。

图 4. 已完成的 viewFeeds 视图
[attach]121[/attach]

[b]查看频道中的最新提要[/b]
       用户单击该链接查看提要的时候,触发了一个新的行为,即 viewChannel 行为。在 FeedController 类中定义此行为,如下所示。

清单 18. 定义 viewChannelAction 方法
[php]                  
    public function viewChannelAction()
    {
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('title');
        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('feeds', '*');
        $sql = $select->__toString();
        $results = $db->fetchAll($sql);
        foreach ($results as $row)
            $feedLink = $row['link'];
        $rssFeed = Zend_Feed::import($feedLink);
        
        $view = Zend::registry('view');
        $view->title = $feedTitle;
        $view->rssFeed = $rssFeed;
        echo $view->render('viewChannel.php');
    }
[/php]

       此方法从 Zend 注册库的 fGet 对象中检索用户想浏览其摘要的提要名称。链接是从数据库中检索而来的,而 RSS 提要数据则检索自该链接,该链接传递到视图对象,viewChannel 行为也从这个链接中检索摘要和链接数据。

[b]viewChannel 视图[/b]
       既然已经获取了 RSS 提要数据,那么让我们把它应用到 viewChannel 视图中,并将这些链接显示给用户。定义 viewChannel 视图,如下所示。

清单 19. 定义 viewChannel 视图
[php]                  
<html>
<head>
    <title><?php echo $this->escape($this->title);
?></title>
</head>
<body>
  [<a href='/'>Back to Main Menu</a>]<br>
  <h1><?php echo $this->escape($this->title); ?></h1>
  
  <table>
    <tr>
      <td>Channel Title (click to read)
              </td>
      <td>Save entry to database</td>
    </tr>
  <?php
     /* Get feeds from the database by title */
     foreach ($this->rssFeed as $item) {
         $entryTitle = $item->title();
         $link = $item->link();
         echo "<tr><td><a
href='$link'>$entryTitle</a></td>";
         echo "<td><a href=\"saveEntry?feedTitle=".
              "$this->title&title=$entryTitle&link=$link\">".
              "Save</a></td></tr>";
     }
?>
  </table>
</body>
</html>
[/php]

       上面视图中的 PHP 代码遍历 rssFeed 对象的每个条目。通过调用 $item->title() 获取摘要名称,而调用 $item->link() 获取文章链接。随后摘要同全文链接一起被显示出来,将此条目保存到数据库的链接一并显示。已完成的 viewChannel 浏览器输出如图 5 所示。

图 5. viewChannel 视图
[attach]122[/attach]

[b]保存、查看及删除提要条目[/b]
       有了可将条目保存到数据库的链接,您还需要定义适当的行为、赋予视图功能以及在不需要的时候删除这些条目。

[b]保存条目[/b]
       保存条目使用户稍后还能够查看这些条目。回顾上文,清单 19 中已介绍了将条目保存到数据库的链接,现在您需要定义行为以使用这个功能。在 FeedController 类中定义 saveEntryAction 方法,如下所示。

清单 20. 定义 saveEntryAction 方法
[php]                  
    public function saveEntryAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('feedTitle');
        $channelTitle = $filterGet->getRaw('title');
        $channelLink = $filterGet->getRaw('link');
        $db = Zend::registry('db');
        $row = array(
                     'Username' => $username,
                     'feedname' => $feedTitle,
                     'channelname' => $channelTitle,
                     'link' => $channelLink
                     );
        $table = 'savedentries';
        $rowsAffected = $db->insert($table, $row);
        $this->_redirect\
        ("/feed/viewChannel?title=$feedTitle");
    }
[/php]

       上述代码从 Zend 注册库的 fSession 对象中检索 username,从 Zend 注册库的 fGet 对象中检索 feedTitle、channelTitle(摘要名称)以及 channelLink(全文链接)。这四个字段随后被保存为一行,保存在数据库的 savedentries 表中。将数据保存到数据库中后,通过在 URL 中设置相同的 feedTitle,用户即被重定向到 viewChannel 行为。

[b]查看已保存条目[/b]
       既然能够将条目保存到数据库中,那么我们需要定义 viewSavedEntries 行为。回顾我们在清单 12 的 viewFeeds 视图中提供的链接。定义 FeedController 类的 viewSavedEntriesAction 方法,如下所示。

清单 21. 定义 viewSavedEntriesAction 方法
[php]                  
    public function viewSavedEntriesAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('savedentries', '*');
        $select->where("username=?", $username);
        $sql = $select->__toString();
        $entries = $db->fetchAll($sql);
        
        $view = Zend::registry('view');
        $view->title = 'View Saved Entries';
        $view->entries = $entries;
        echo $view->render('viewSavedEntries.php');
    }
[/php]

       此行为从 Zend 注册库的 fSession 对象中检索 username,然后设置一个查询,检索用户已订阅的所有提要,并将结果传至 viewSavedEntries 视图。

[b]viewSavedEntries 视图[/b]
       清单 21 中呈现的视图展示了用户已保存的所有条目。定义 FeedController 类中的 viewSavedEntriesAction 方法,如下所示。

清单 22. 定义 viewSavedEntries 视图
[php]                 
<html>
<head>
  <title><?php echo $this->escape($this->title);
?></title>
</head>
<body>
  [<a href='/'>Back to Main Menu</a>]<br>
  <h1><?php echo $this->escape($this->title);
?></h1>
  
  <table>
    <tr>
      <td>Feed > Title (Click to View)
              </td>
      <td>Delete Channel Entry</td>
    </tr>
  <?php
     /* Get feeds from the database by title */
     foreach ($this->entries as $row) {
         $link = $row['link'];
         $channelTitle = $row['channelname'];
         $feedTitle = $row['feedname'];
         echo "<tr><td><a href='$link'>".
              "$feedTitle > $channelTitle</a></td>";
         echo "<td><a
href=\"feed/deleteEntry?feedTitle=$feedTitle".
              "&channelTitle=$channelTitle&link=$link\">".
              "Delete</a></td></tr>";
     }
?>
  </table>
</body>
</html>
[/php]

       该视图的核心是循环遍历当前用户已保存的所有条目,显示标题和指向全文的链接,以及从数据库中删除该条目的链接。已完成的 viewSavedEntries 视图的浏览器输出如图 6 所示,该图显示了几条已保存条目。

图 6. viewSavedEntries 视图
[attach]123[/attach]

[b]删除条目[/b]
       当用户请求从数据库中删除一个条目之后,deleteEntryAction 方法被调用,将该条目从数据库中删除。在 FeedController 中定义此方法,如下所示。

清单 23. 定义 deleteEntryAction 方法
[php]                    
    public function deleteEntryAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('feedTitle');
        $channelTitle = $filterGet->getRaw('channelTitle');
        $db = Zend::registry('db');
        $table = 'savedentries';
        $where = "username='$username' and feedname='$feedTitle'".
                 " and channelname='$channelTitle'";
        $rowsAffected = $db->delete($table, $where);
        $this->_redirect('/feed/viewSavedEntries/');
    }
[/php]

       上述代码从 Zend 注册库的 fSession 对象中检索用户名,并从 Zend 注册库的 fGet 对象中检索 feedTitle、channelTitle(摘要名称)和 channelLink(全文链接),正如清单 20 中所示。删除一个条目后的浏览器输出如图 7 所示。

图 7. 删除条目
[attach]124[/attach]

       这样就完成了我们的提要阅读器!在接下来的部分中,我们将定义最后两个管理任务。

[color=#ff0000]ZendChina官方资讯,转载请以链接形式注名来源:[/color][url=http://www.zendchina.net/][color=#ff0000]ZendChina[/color][/url][color=#ff0000] - [/color][url=http://bbs.zendchina.net/thread-95-1-1.html][color=#ff0000]Zend Framework 提示信息(二)[/color][/url]

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.