From c96f324b15ac69771b12278f33027c47a425fefa Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Mon, 13 Sep 2010 10:58:50 -0400 Subject: [PATCH] Initial commit of H4 changes to Jonah, merged from the H4-Jonah branch. Squashed commit of the following: commit a57fb8ab6805d93e24c32adfe4f900fd9723ed83 Author: Michael J. Rubinsky Date: Fri Aug 13 18:51:52 2010 -0400 Use ckeditor, not fckeditor commit 596101806148a1d0aebb1964c5e7bf8eb0656858 Author: Michael J. Rubinsky Date: Fri Aug 13 18:46:18 2010 -0400 Fix path to sidebar commit 8a057adee7be185b7c60ad1be2db1928439e4577 Author: Michael J. Rubinsky Date: Fri Aug 13 18:42:31 2010 -0400 More H4 changes commit dd0bf24f4f69f88e760586061b14147b73fce849 Author: Michael J. Rubinsky Date: Sat Jul 17 11:54:09 2010 -0400 no more composite feeds either commit 8ca4604b21b0f5f53fec362c600ee9e6714dba67 Author: Michael J. Rubinsky Date: Fri Jul 16 19:45:33 2010 -0400 Start working on routable feed delivery requests. commit 85f74642c1869644b97f08657ede339119269abb Author: Michael J. Rubinsky Date: Fri Jul 16 17:58:07 2010 -0400 re-add routes definition file, instantiate the mapper in dispatch.php commit 6bd49d1c31bca54c9fbf9af8a3fe6912af4a3588 Author: Michael J. Rubinsky Date: Fri Jul 16 17:22:05 2010 -0400 pdf generation view commit 4d0ba9c055dc45b8ad59c584a30a9b4f4ff256eb Author: Michael J. Rubinsky Date: Fri Jul 16 16:59:02 2010 -0400 story deletion view commit 691cf253cee9340e8646cf36195a3c866fbad2b6 Author: Michael J. Rubinsky Date: Fri Jul 16 16:45:28 2010 -0400 move story editing to a view object. This will probably get refactored again, to remove the Horde_Form usage to give more control over the RTE, but for now, just leave it based on Horde_Form commit 80205df3710417a4bd88ea1d11d1e277b3ea313e Author: Michael J. Rubinsky Date: Fri Jul 16 16:32:27 2010 -0400 story lists and story views to Jonah_View commit 37c65c5b819bba634686bd1ddfbb4ce5d46f0fc6 Author: Michael J. Rubinsky Date: Fri Jul 16 15:14:03 2010 -0400 view for channel editing commit 348406b09781fd0868ab0b804af3ccfe9556c79f Author: Michael J. Rubinsky Date: Fri Jul 16 14:56:41 2010 -0400 ChannelDelete view commit 9b72046aa762f45d58c639d928d8d8825c793f9c Author: Michael J. Rubinsky Date: Fri Jul 16 13:57:40 2010 -0400 this method needs to take an array commit c2fe084894ad8421a274ca0257da090b5146d047 Author: Michael J. Rubinsky Date: Fri Jul 16 13:56:49 2010 -0400 Start adding formal Jonah_View classes. This adds the channel list view. commit 0775dea7ea23c4d2dbbfc16f19914225d5103ff2 Author: Michael J. Rubinsky Date: Fri Jul 16 11:18:42 2010 -0400 remove deprecated method commit 94bb499433bb89ea263a4b000bf0b37fb0848aeb Author: Michael J. Rubinsky Date: Fri Jul 16 11:14:18 2010 -0400 Resolve conflict - missed this during last merge. commit 52f7f22598c20c104cc38368faa6987955a88146 Author: Michael J. Rubinsky Date: Thu Jul 15 17:47:16 2010 -0400 simplify commit 02a19dafff869dbc187a5c2dc3d8ad301aaf8fab Author: Michael J. Rubinsky Date: Thu Jul 15 17:39:41 2010 -0400 Horde_View style templating for story view. commit b7bec9e96df0ec6d77a70f05896fae72ed0ca4bd Author: Michael J. Rubinsky Date: Thu Jul 15 13:48:52 2010 -0400 only show sidebar if not in an ajax view commit d7095ab0cc85050f4185db0be1b5567fe933e8d0 Author: Michael J. Rubinsky Date: Thu Jul 15 13:47:54 2010 -0400 Horde_View for the stories index page. This just moves existing templates to Horde_View, still need to rethink the layout, use of renderPartial, helpers etc... commit 419ca9a3e914198d649c387330b87e5f86c50a08 Author: Michael J. Rubinsky Date: Wed Jul 14 16:14:58 2010 -0400 Hopefully the last of the Jonah_News usage is now removed. commit 2a6760a484a70cd43f20e89b8013c253ea181791 Author: Michael J. Rubinsky Date: Fri Jul 9 18:50:40 2010 -0400 we still have composite channels commit 968d42008125617bee6c1a834a10678ca86a9fc0 Author: Michael J. Rubinsky Date: Fri Jul 9 18:49:53 2010 -0400 Use Horde_View for channel listing, remove needlessly complicated template rendering for channel views commit 10e46cc2d98a99f43c29b62fa9619d810a329b0e Author: Michael J. Rubinsky Date: Fri Jul 9 18:48:22 2010 -0400 no need for aggregate view commit 7ffd42aab69fe45dafa275848ecb886fe2417d71 Author: Michael J. Rubinsky Date: Fri Jul 9 17:18:47 2010 -0400 getAvailableTypes() should be in Jonah:: commit cd9df0094b965cc11755e16cfd159630ebe8a8c0 Author: Michael J. Rubinsky Date: Fri Jul 9 16:48:16 2010 -0400 This doesn't look right to me. Not sure why we wouldn't want the application's webroot if we are generating a full url. commit f80000f601a3ad579f1e77a4325caa9eb038d7a0 Author: Michael J. Rubinsky Date: Tue Jul 6 17:27:04 2010 -0400 Further work on making Jonah a content authoring application. Move all code over to use Jonah_Driver, and not Jonah_News (this means Jonah now now longer has anything to do with external channels) H4-ify, exceptions, prune dead code commit 1700e73ac10461dcdd1db099af44ebd1da403ee7 Author: Michael J. Rubinsky Date: Sat Jul 3 18:18:45 2010 -0400 fix timezone determination when user's timezone pref is empty/default. commit 73d6b4073173f32d153a62ecf3d7cbeec2e04a45 Author: Michael J. Rubinsky Date: Sat Jul 3 15:14:42 2010 -0400 Horde 4 CS, minor logic tweaks. commit 2d0a3ca5b83ea5ee9cff65a446a7896d377e9eea Author: Michael J. Rubinsky Date: Sat Jul 3 15:13:14 2010 -0400 Horde 4 cleanup, catch exceptions. This block is deprecated and will be going away... commit 68c4bef361ee907c9de3bde63f4254a93058fc25 Author: Michael J. Rubinsky Date: Sat Jul 3 13:38:15 2010 -0400 This block doesn't need the deprecated News object, use the new Jonah_Driver. Some other H4 fixes as well. commit 7f4c3e3b785499cc798ea3096d9edefe6f439580 Author: Michael J. Rubinsky Date: Sat Jul 3 13:31:14 2010 -0400 remove unused method, note that this file will be removed in the future --- jonah/channels/aggregate.php | 150 ------- jonah/channels/delete.php | 85 +--- jonah/channels/edit.php | 91 +--- jonah/channels/index.php | 90 +--- jonah/config/routes.php.dist | 29 ++ jonah/delivery/html.php | 58 +-- jonah/delivery/index.php | 4 +- jonah/delivery/rss.php | 62 +-- jonah/dispatcher.php | 43 +- jonah/docs/lighttpd-jonah.conf | 15 + jonah/lib/Api.php | 163 ++++--- jonah/lib/Application.php | 33 +- jonah/lib/Block/cloud.php | 17 +- jonah/lib/Block/delivery.php | 2 +- jonah/lib/Block/latest.php | 49 ++- jonah/lib/Block/news.php | 26 +- jonah/lib/Block/news_popular.php | 14 +- jonah/lib/Block/story.php | 47 +- jonah/lib/Driver.php | 139 ++---- jonah/lib/Driver/Sql.php | 561 ++++++++++-------------- jonah/lib/FeedParser.php | 2 + jonah/lib/Form/Feed.php | 55 +++ jonah/lib/{Forms => Form}/Story.php | 50 +-- jonah/lib/Forms/Feed.php | 128 ------ jonah/lib/Jonah.php | 71 ++- jonah/lib/View/Base.php | 49 +++ jonah/lib/View/ChannelDelete.php | 81 ++++ jonah/lib/View/ChannelEdit.php | 69 +++ jonah/lib/View/ChannelList.php | 74 ++++ jonah/lib/View/DeliveryHtml.php | 67 +++ jonah/lib/View/StoryDelete.php | 88 ++++ jonah/lib/View/StoryEdit.php | 81 ++++ jonah/lib/View/StoryList.php | 120 +++++ jonah/lib/View/StoryPdf.php | 70 +++ jonah/lib/View/StoryView.php | 105 +++++ jonah/stories/delete.php | 91 +--- jonah/stories/edit.php | 75 +--- jonah/stories/index.php | 124 +----- jonah/stories/pdf.php | 77 +--- jonah/stories/results.php | 66 +-- jonah/stories/share.php | 43 +- jonah/stories/view.php | 114 +---- jonah/templates/channels/index.html | 55 --- jonah/templates/common-header.inc | 2 +- jonah/templates/delivery/rss.xml | 6 +- jonah/templates/delivery/rss2.xml | 10 +- jonah/templates/delivery/rss2_full.xml | 10 +- jonah/templates/delivery/rss_full.xml | 8 +- jonah/templates/menu.inc | 2 + jonah/templates/stories/index.html | 55 --- jonah/templates/stories/index.html.php | 50 +++ jonah/templates/stories/layout/view.html.php | 23 + jonah/templates/stories/partial/_story.html.php | 22 + jonah/templates/stories/story.html | 15 - jonah/templates/stories/view.html | 23 - jonah/templates/view/channellist.html.php | 54 +++ 56 files changed, 1785 insertions(+), 1928 deletions(-) delete mode 100644 jonah/channels/aggregate.php create mode 100644 jonah/config/routes.php.dist create mode 100644 jonah/docs/lighttpd-jonah.conf create mode 100644 jonah/lib/Form/Feed.php rename jonah/lib/{Forms => Form}/Story.php (58%) delete mode 100644 jonah/lib/Forms/Feed.php create mode 100644 jonah/lib/View/Base.php create mode 100644 jonah/lib/View/ChannelDelete.php create mode 100644 jonah/lib/View/ChannelEdit.php create mode 100644 jonah/lib/View/ChannelList.php create mode 100644 jonah/lib/View/DeliveryHtml.php create mode 100644 jonah/lib/View/StoryDelete.php create mode 100644 jonah/lib/View/StoryEdit.php create mode 100644 jonah/lib/View/StoryList.php create mode 100644 jonah/lib/View/StoryPdf.php create mode 100644 jonah/lib/View/StoryView.php delete mode 100644 jonah/templates/channels/index.html create mode 100644 jonah/templates/menu.inc delete mode 100644 jonah/templates/stories/index.html create mode 100644 jonah/templates/stories/index.html.php create mode 100644 jonah/templates/stories/layout/view.html.php create mode 100644 jonah/templates/stories/partial/_story.html.php delete mode 100644 jonah/templates/stories/story.html delete mode 100644 jonah/templates/stories/view.html create mode 100644 jonah/templates/view/channellist.html.php diff --git a/jonah/channels/aggregate.php b/jonah/channels/aggregate.php deleted file mode 100644 index 38d9c3608..000000000 --- a/jonah/channels/aggregate.php +++ /dev/null @@ -1,150 +0,0 @@ - - */ - -require_once dirname(__FILE__) . '/../lib/Application.php'; -$jonah = Horde_Registry::appInit('jonah'); - -function _getLinks($id, $subid, $name, $title) -{ - $url = Horde::url('channels/aggregate.php'); - $url = Horde_Util::addParameter($url, 'channel_id', $id); - $url = Horde_Util::addParameter($url, 'subchannel_id', $subid); - $edit = array('url' => Horde_Util::addParameter($url,'action', 'edit'), 'text' => sprintf(_("Edit channel \"%s\""), $name), 'title' => $title); - $delete = array('url' => Horde_Util::addParameter($url, 'action', 'delete'), 'text' => sprintf(_("Remove channel \"%s\""), $name), 'title' => $title); - return array($edit, $delete); -} - -$news = Jonah_News::factory(); -$renderer = new Horde_Form_Renderer(); -$vars = Horde_Variables::getDefaultVariables(); - -/* Set up some variables. */ -$channel_id = $vars->get('channel_id'); -$channel = $news->getChannel($channel_id); -if ($channel instanceof PEAR_Error) { - throw new Jonah_Exception($channel); -} -$channel_name = $channel['channel_name']; -$ids = preg_split('/:/', $channel['channel_url'], -1, PREG_SPLIT_NO_EMPTY); - -/* Get the vars for channel type. */ -$channel_type = $channel['channel_type']; -if ($channel_type != Jonah::AGGREGATED_CHANNEL) { - $notification->push(_("This is no aggregated channel."), 'horde.error'); - Horde::url('channels/edit.php', true) - ->add('channel_id', $channel_id) - ->redirect(); -} - -/* Check permissions and deny if not allowed. */ -if (!Jonah::checkPermissions(Jonah::typeToPermName($channel_type), Horde_Perms::EDIT, $channel_id)) { - $notification->push(_("You are not authorised for this action."), 'horde.warning'); - Horde::authenticationFailureRedirect(); -} - -/* Set up the form. */ -$form = new Horde_Form($vars, sprintf(_("Aggregated channels for channel \"%s\""), $channel_name), 'channel_aggregate'); -$form->setButtons(_("Add")); -$form->addHidden('', 'channel_id', 'int', false); -$form->addVariable(_("Channel Name"), 'channel_name', 'text', true); -$form->addVariable(_("Source URL"), 'channel_url', 'text', true, false, _("The url to use to fetch the stories, for example 'http://www.example.com/stories.rss'")); -$form->addVariable(_("Link"), 'channel_link', 'text', false); -$form->addVariable(_("Image"), 'channel_img', 'text', false); - -if ($form->validate($vars)) { - $subchannel = array('channel_url' => $vars->get('channel_url'), - 'channel_name' => $vars->get('channel_name'), - 'channel_link' => $vars->get('channel_link'), - 'channel_img' => $vars->get('channel_img'), - 'channel_type' => Jonah::EXTERNAL_CHANNEL); - if ($vars->get('subchannel_id')) { - $subchannel['channel_id'] = $vars->get('subchannel_id'); - } - $save = $news->saveChannel($subchannel); - if (is_a($save, 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error saving the channel: %s"), $save->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The channel \"%s\" has been saved."), $vars->get('channel_name')), 'horde.success'); - if (!$vars->get('subchannel_id')) { - $ids[] = $save; - $channel['channel_url'] = implode(':', $ids); - $save = $news->saveChannel($channel); - if (is_a($save, 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error updating the channel: %s"), $save->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The channel \"%s\" has been updated."), $channel['channel_name']), 'horde.success'); - } - } - - Horde::url('channels/aggregate.php', true) - ->add('channel_id', $channel_id) - ->redirect(); - } -} elseif ($vars->get('action') == 'delete') { - $subchannel = $news->getChannel($vars->get('subchannel_id')); - $result = $news->deleteChannel($vars->get('subchannel_id')); - if (is_a($result, 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error removing the channel: %s"), $result->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The channel \"%s\" has been removed."), $subchannel['channel_name']), 'horde.success'); - array_splice($ids, array_search($subchannel['channel_id'], $ids), 1); - $channel['channel_url'] = implode(':', $ids); - $save = $news->saveChannel($channel); - if (is_a($save, 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error updating the channel: %s"), $save->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The channel \"%s\" has been updated."), $channel['channel_name']), 'horde.success'); - } - } - - Horde::url('channels/aggregate.php', true) - ->add('channel_id', $channel_id) - ->redirect(); -} elseif ($vars->get('action') == 'edit') { - $form->addHidden('', 'subchannel_id', 'int', false); - $form->setButtons(_("Update")); - $subchannel = $news->getChannel($vars->get('subchannel_id')); - $vars->set('channel_name', $subchannel['channel_name']); - $vars->set('channel_url', $subchannel['channel_url']); - $vars->set('channel_link', $subchannel['channel_link']); - $vars->set('channel_img', $subchannel['channel_img']); -} - -foreach ($ids as $id) { - $subchannel = $news->getChannel($id); - if (is_a($subchannel, 'PEAR_Error')) { - $name = $subchannel->getMessage(); - $url = ''; - } elseif (empty($subchannel['channel_name'])) { - $name = $subchannel['channel_url']; - $url = $subchannel['channel_url']; - } else { - $name = $subchannel['channel_name']; - $url = $subchannel['channel_url']; - } - $form->insertVariableBefore('channel_name', '', 'subchannel' . $id, 'link', false, false, null, array(_getLinks($channel_id, $id, $name, $url))); -} - -Horde::startBuffer(); -$form->renderActive($renderer, $vars, 'aggregate.php', 'post'); -$main = Horde::endBuffer(); - -$template = new Horde_Template(); -$template->set('main', $main); -$template->set('menu', Horde::menu()); - -// Buffer the notifications and send to the template -Horde::startBuffer(); -$GLOBALS['notification']->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); - -require JONAH_TEMPLATES . '/common-header.inc'; -echo $template->fetch(JONAH_TEMPLATES . '/main/main.html'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/jonah/channels/delete.php b/jonah/channels/delete.php index 670cc2d5b..b31f761c0 100644 --- a/jonah/channels/delete.php +++ b/jonah/channels/delete.php @@ -1,89 +1,22 @@ * @author Marko Djukic + * @author Michael J. Rubinsky + * @package Jonah */ - require_once dirname(__FILE__) . '/../lib/Application.php'; -$jonah = Horde_Registry::appInit('jonah'); -require_once 'Horde/Form.php'; -require_once 'Horde/Form/Renderer.php'; - -$news = Jonah_News::factory(); +Horde_Registry::appInit('jonah'); /* Set up the form variables and the form. */ -$vars = Horde_Variables::getDefaultVariables(); -$form_submit = $vars->get('submitbutton'); -$channel_id = $vars->get('channel_id'); - -$channel = $news->getChannel($channel_id); -if (is_a($channel, 'PEAR_Error')) { - $notification->push(_("Invalid channel specified for deletion."), 'horde.message'); - Horde::url('channels/index.php', true)->redirect(); -} - -/* Check permissions and deny if not allowed. */ -if (!Jonah::checkPermissions(Jonah::typeToPermName($channel['channel_type']), Horde_Perms::DELETE, $channel_id)) { - $notification->push(_("You are not authorised for this action."), 'horde.warning'); - Horde::authenticationFailureRedirect(); -} - -/* If not yet submitted set up the form vars from the fetched - * channel. */ -if (empty($form_submit)) { - $vars = new Horde_Variables($channel); -} - -$title = sprintf(_("Delete News Channel \"%s\"?"), $vars->get('channel_name')); -$form = new Horde_Form($vars, $title); - -$form->setButtons(array(_("Delete"), _("Do not delete"))); -$form->addHidden('', 'channel_id', 'int', true, true); - -$msg = _("Really delete this News Channel?"); -if ($vars->get('channel_type') == Jonah::INTERNAL_CHANNEL) { - $msg .= ' ' . _("All stories created in this channel will be lost!"); -} else { - $msg .= ' ' . _("Any cached stories for this channel will be lost!"); -} -$form->addVariable($msg, 'confirm', 'description', false); - -if ($form_submit == _("Delete")) { - if ($form->validate($vars)) { - $form->getInfo($vars, $info); - $delete = $news->deleteChannel($info); - if (is_a($delete, 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error deleting the channel: %s"), $delete->getMessage()), 'horde.error'); - } else { - $notification->push(_("The channel has been deleted."), 'horde.success'); - Horde::url('channels/index.php', true)->redirect(); - } - } -} elseif (!empty($form_submit)) { - $notification->push(_("Channel has not been deleted."), 'horde.message'); - Horde::url('channels/index.php', true)->redirect(); -} - -$template = new Horde_Template(); - -// Buffer the main form and send to the template -Horde::startBuffer(); -$form->renderActive(null, $vars, 'delete.php', 'post'); -$template->set('main', Horde::endBuffer()); -$template->set('menu', Horde::menu()); - -// Buffer the notifications and send to the template -Horde::startBuffer(); -$GLOBALS['notification']->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); +$params = array('vars' => Horde_Variables::getDefaultVariables(), + 'registry' => &$registry, + 'notification' => &$notification); -require JONAH_TEMPLATES . '/common-header.inc'; -echo $template->fetch(JONAH_TEMPLATES . '/main/main.html'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; +$view = new Jonah_View_ChannelDelete($params); +$view->run(); diff --git a/jonah/channels/edit.php b/jonah/channels/edit.php index b7c198d60..8890dbb72 100644 --- a/jonah/channels/edit.php +++ b/jonah/channels/edit.php @@ -1,95 +1,22 @@ * @author Marko Djukic + * @author Michael J. Rubinsky + * @package Jonah */ require_once dirname(__FILE__) . '/../lib/Application.php'; -$jonah = Horde_Registry::appInit('jonah'); -require_once JONAH_BASE . '/lib/Forms/Feed.php'; -require_once 'Horde/Form/Renderer.php'; - -$news = Jonah_News::factory(); - -/* Set up the form variables and the form. */ -$vars = Horde_Variables::getDefaultVariables(); -$form = new FeedForm($vars); - -/* Set up some variables. */ -$formname = $vars->get('formname'); -$channel_id = $vars->get('channel_id'); - -/* Form not yet submitted and is being edited. */ -if (!$formname && $channel_id) { - $vars = new Horde_Variables($news->getChannel($channel_id)); -} - -/* Get the vars for channel type. */ -$channel_type = $vars->get('channel_type'); -$old_channel_type = $vars->get('old_channel_type'); -$changed_type = false; - -/* Check permissions and deny if not allowed. */ -if (!Jonah::checkPermissions(Jonah::typeToPermName($channel_type), Horde_Perms::EDIT, $channel_id)) { - $notification->push(_("You are not authorised for this action."), 'horde.warning'); - Horde::authenticationFailureRedirect(); -} - -/* If this is null then new form, so set both to default. */ -if (is_null($channel_type)) { - $channel_type = Jonah_News::getDefaultType(); - $old_channel_type = $channel_type; -} - -/* Check if channel type has been changed and notify. */ -if ($channel_type != $old_channel_type && $formname) { - $changed_type = true; - $notification->push(_("Feed type changed."), 'horde.message'); -} -$vars->set('old_channel_type', $channel_type); - -/* Output the extra fields required for this channel type. */ -$form->setExtraFields($channel_type, $channel_id); - -if ($formname && !$changed_type) { - if ($form->validate($vars)) { - $form->getInfo($vars, $info); - $save = $news->saveChannel($info); - if (is_a($save, 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error saving the feed: %s"), $save->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The feed \"%s\" has been saved."), $info['channel_name']), 'horde.success'); - if ($channel_type == Jonah::AGGREGATED_CHANNEL) { - $notification->push(_("You can now edit the sub-feeds."), 'horde.message'); - } else { - Horde::url('channels/index.php', true)->redirect(); - } - } - } -} - -$renderer = new Horde_Form_Renderer(); -Horde::startBuffer(); -$form->renderActive($renderer, $vars, 'edit.php', 'post'); -$main = Horde::endBuffer(); - -$template = new Horde_Template(); -$template->set('main', $main); -$template->set('menu', Horde::menu()); +Horde_Registry::appInit('jonah'); -// Buffer the notifications and send to the template -Horde::startBuffer(); -$GLOBALS['notification']->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); +$params = array('vars' => Horde_Variables::getDefaultVariables(), + 'registry' => &$registry, + 'notification' => &$notification); -$title = $form->getTitle(); -require JONAH_TEMPLATES . '/common-header.inc'; -echo $template->fetch(JONAH_TEMPLATES . '/main/main.html'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; +$view = new Jonah_View_ChannelEdit($params); +$view->run(); diff --git a/jonah/channels/index.php b/jonah/channels/index.php index cb252f38d..9eea17b9b 100644 --- a/jonah/channels/index.php +++ b/jonah/channels/index.php @@ -1,99 +1,37 @@ * @author Marko Djukic + * @author Michael J. Rubinsky + * @package Jonah */ require_once dirname(__FILE__) . '/../lib/Application.php'; -$jonah = Horde_Registry::appInit('jonah'); +Horde_Registry::appInit('jonah'); if (!Jonah::checkPermissions('jonah:news', Horde_Perms::EDIT)) { $notification->push(_("You are not authorised for this action."), 'horde.warning'); $registry->authenticateFailure(); } -$have_news = Jonah_News::getAvailableTypes(); +$have_news = Jonah::getAvailableTypes(); if (empty($have_news)) { $notification->push(_("News is not enabled."), 'horde.warning'); - Horde::url('index.php', true)->redirect(); -} - -$news = Jonah_News::factory(); - -$channels = $news->getChannels(array_keys($have_news)); -if (is_a($channels, 'PEAR_Error')) { - $notification->push(sprintf(_("An error occurred fetching channels: %s"), $channels->getMessage()), 'horde.error'); - $channels = false; -} elseif ($channels) { - $channels = Jonah::checkPermissions('channels', Horde_Perms::SHOW, $channels); - /* Build channel specific fields. */ - foreach ($channels as $key => $channel) { - /* Edit channel link. */ - $url = Horde::url('channels/edit.php'); - $url = Horde_Util::addParameter($url, 'channel_id', $channel['channel_id']); - $channels[$key]['edit_link'] = Horde::link($url, _("Edit channel"), '', '', '', _("Edit channel")) . Horde::img('edit.png') . ''; - - /* Delete channel link. */ - $url = Horde::url('channels/delete.php'); - $url = Horde_Util::addParameter($url, 'channel_id', $channel['channel_id']); - $channels[$key]['delete_link'] = Horde::link($url, _("Delete channel"), '', '', '', _("Delete channel")) . Horde::img('delete.png') . ''; - /* View stories link. */ - $url = Horde::url('stories/index.php'); - $url = Horde_Util::addParameter($url, 'channel_id', $channel['channel_id']); - $channels[$key]['stories_url'] = $url; - - /* Channel type specific links. */ - $channels[$key]['addstory_link'] = ''; - $channels[$key]['refresh_link'] = ''; - - switch ($channel['channel_type']) { - case Jonah::INTERNAL_CHANNEL: - /* Add story link. */ - $url = Horde::url('stories/edit.php'); - $url = Horde_Util::addParameter($url, 'channel_id', $channel['channel_id']); - $channels[$key]['addstory_link'] = Horde::link($url, _("Add story"), '', '', '', _("Add story")) . Horde::img('new.png') . ''; - break; - - case Jonah::EXTERNAL_CHANNEL: - case Jonah::AGGREGATED_CHANNEL: - /* Refresh cache link. */ - $url = Horde::url('stories/index.php'); - $url = Horde_Util::addParameter($url, array('channel_id' => $channel['channel_id'], 'refresh' => '1', 'url' => Horde::selfUrl())); - $channels[$key]['refresh_link'] = Horde::link($url, _("Refresh channel"), '', '', '', _("Refresh channel")) . Horde::img('reload.png') . ''; - break; - } - - $channels[$key]['channel_type'] = Jonah::getChannelTypeLabel($channel['channel_type']); - /* TODO: pref setting for date display. */ - $channels[$key]['channel_updated'] = ($channel['channel_updated'] ? date('M d, Y H:i', (int)$channel['channel_updated']) : '-'); - } + $url = Horde::url('index.php'); + header('Location: ' . $url); + exit; } -$template = new Horde_Template(); -$template->set('header', _("Manage Feeds")); -$template->set('listheaders', array(array('attrs' => ' class="sortdown"', 'label' => _("Name")), - array('attrs' => '', 'label' => _("Type")), - array('attrs' => '', 'label' => _("Last Update")))); -$template->set('channels', $channels, true); -$template->set('menu', Horde::menu()); -$template->set('search_img', Horde::img('search.png')); - -// Buffer the notifications and send to the template -Horde::startBuffer(); -$GLOBALS['notification']->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); +$params = array('notification' => &$notification, + 'prefs' => &$prefs, + 'registry' => &$registry + ); -$title = _("Feeds"); -Horde::addScriptFile('tables.js', 'horde', true); -Horde::addScriptFile('quickfinder.js', 'horde', true); -require JONAH_TEMPLATES . '/common-header.inc'; -echo $template->fetch(JONAH_TEMPLATES . '/channels/index.html'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; +$view = new Jonah_View_ChannelList($params); +$view->run(); \ No newline at end of file diff --git a/jonah/config/routes.php.dist b/jonah/config/routes.php.dist new file mode 100644 index 000000000..12942c167 --- /dev/null +++ b/jonah/config/routes.php.dist @@ -0,0 +1,29 @@ +connect('Admin', '/admin/:section/:page', array( + 'controller' => 'admin', + 'section' => '', + 'page' => '', +)); + +// Valid filter names are "author", "tag" and "date" +// @TODO represent those with route requirements +$m->connect('Default', '/feeds/:feed/:filter/:value', array( + 'controller' => 'feed', + 'feed' => '', + 'filter' => '', + 'value' => '', +)); + +// api endpoint for getting post counts? +//$m->connect('/feeds/:feed/-/posts/count', array( +// 'controller' => 'api', +// 'action' => 'count')); + + +// Local route overrides +if (file_exists(dirname(__FILE__) . '/routes.local.php')) { + include dirname(__FILE__) . '/routes.local.php'; +} diff --git a/jonah/delivery/html.php b/jonah/delivery/html.php index 06cecdf04..cbc79b73b 100644 --- a/jonah/delivery/html.php +++ b/jonah/delivery/html.php @@ -2,7 +2,7 @@ /** * Script to handle requests for html delivery of stories. * - * Copyright 2004-2009 The Horde Project (http://www.horde.org/) + * Copyright 2004-2010 The Horde Project (http://www.horde.org/) * * See the enclosed file LICENSE for license information (BSD). If you did not * did not receive this file, see http://cvs.horde.org/co.php/jonah/LICENSE. @@ -15,56 +15,22 @@ $jonah = Horde_Registry::appInit('jonah', array( 'authentication' => 'none', 'session_control' => 'readonly' )); -require JONAH_BASE . '/config/templates.php'; - -// TODO - check if a user, have button to add channel to their -// personal aggregated channel. - -$news = Jonah_News::factory(); /* Get the id and format of the channel to display. */ $criteria = Horde_Util::nonInputVar('criteria'); if (!$criteria) { - $criteria['channel_id'] = Horde_Util::getFormData('channel_id'); - $criteria['channel_format'] = Horde_Util::getFormData('format'); + $criteria['feed'] = Horde_Util::getFormData('channel_id'); + $criteria['format'] = Horde_Util::getFormData('format'); } - -if (empty($criteria['channel_format'])) { +if (empty($criteria['format'])) { // Select the default channel format - $criteria['channel_format'] = key($templates); -} - -/* Get requested channel. */ -$channel = $news->getChannel($criteria['channel_id']); -if (is_a($channel, 'PEAR_Error')) { - Horde::logMessage($channel, 'ERR'); - $notification->push(_("Invalid channel."), 'horde.error'); - Horde::url('delivery/index.php', true)->redirect(); + // TODO: FIXME + $criteria['format'] = 'standard'; } -$title = sprintf(_("HTML Delivery for \"%s\""), $channel['channel_name']); - -$options = array(); -foreach ($templates as $key => $info) { - $options[] = ''; -} - -$template = new Horde_Template(); -$template->setOption('gettext', 'true'); -$template->set('url', Horde::selfUrl()); -$template->set('session', Horde_Util::formInput()); -$template->set('channel_id', $criteria['channel_id']); -$template->set('channel_name', $channel['channel_name']); -$template->set('format', $criteria['channel_format']); -$template->set('options', $options); -$template->set('stories', $news->renderChannel($criteria['channel_id'], $criteria['channel_format'])); -$template->set('menu', Horde::menu()); - -// Buffer the notifications and send to the template -Horde::startBuffer(); -$GLOBALS['notification']->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); - -require JONAH_TEMPLATES . '/common-header.inc'; -echo $template->fetch(JONAH_TEMPLATES . '/delivery/html.html'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; +$params = array('registry' => &$registry, + 'notification' => &$notification, + 'conf' => &$conf, + 'criteria' => &$criteria); +$view = new Jonah_View_DeliveryHtml($params); +$view->run(); diff --git a/jonah/delivery/index.php b/jonah/delivery/index.php index 6669b3d97..c23fbe359 100644 --- a/jonah/delivery/index.php +++ b/jonah/delivery/index.php @@ -1,15 +1,13 @@ */ - $parts = explode('/', Horde_Util::getPathInfo()); $lastpart = null; $deliveryType = null; diff --git a/jonah/delivery/rss.php b/jonah/delivery/rss.php index 197d9222e..d50b881cf 100644 --- a/jonah/delivery/rss.php +++ b/jonah/delivery/rss.php @@ -1,42 +1,41 @@ */ - require_once dirname(__FILE__) . '/../lib/Application.php'; $jonah = Horde_Registry::appInit('jonah', array( 'authentication' => 'none', 'session_control' => 'readonly' )); -$news = Jonah_News::factory(); +$driver = $GLOBALS['injector']->getInstance('Jonah_Driver'); -// See if the criteria has already been loaded by the index page +/* See if the criteria has already been loaded by the index page */ $criteria = Horde_Util::nonInputVar('criteria'); if (!$criteria) { - $criteria = array(); - $criteria['channel_id'] = Horde_Util::getFormData('channel_id'); - $criteria['tag_id'] = Horde_Util::getFormData('tag_id'); - $criteria['feed_type'] = basename(Horde_Util::getFormData('type')); + $criteria = array( + 'channel_id' => Horde_Util::getFormData('channel_id'), + 'tag_id' => Horde_Util::getFormData('tag_id'), + 'feed_type' => basename(Horde_Util::getFormData('type')) + ); } +/* Default to RSS2 */ if (empty($criteria['feed_type'])) { - // If not specified, default to RSS2 $criteria['feed_type'] = 'rss2'; } /* Fetch the channel info and the story list and check they are both valid. * Do a simple exit in case of errors. */ - - -$channel = $news->getChannel($criteria['channel_id']); -if (is_a($channel, 'PEAR_Error')) { - Horde::logMessage($channel, 'ERR'); +try { + $channel = $driver->getChannel($criteria['channel_id']); +} catch (Exception $e) { + Horde::logMessage($e, 'ERR'); header('HTTP/1.0 404 Not Found'); echo ' @@ -48,19 +47,25 @@ if (is_a($channel, 'PEAR_Error')) { exit; } -/* Check for a tag search. */ +/* Build search array */ +$search = array('channel_id' => $criteria['channel_id'], + 'tags' => array($criteria['tag_id'], + 'limit' => 10)); + +/* Used in template for channel name */ if (!empty($criteria['tag_id'])) { - $tag_name = array_shift($news->getTagNames(array($criteria['tag_id']))); - $stories = $news->searchTagsById(array($criteria['tag_id']), 10, 0, array($criteria['channel_id'])); -} else { - $stories = $news->getStories($criteria['channel_id'], 10, 0, false, time()); + $tag_name = array_shift($driver->getTagNames(array($criteria['tag_id']))); } -if (is_a($stories, 'PEAR_Error')) { - Horde::logMessage($stories, 'ERR'); + +/* Fetch stories */ +try { + $stories = $driver->getStories($criteria); +} catch (Exception $e) { + Horde::logMessage($e, 'ERR'); $stories = array(); } - +/* Build the template (@TODO: Use Horde_View) */ $template = new Horde_Template(); $template->set('charset', $GLOBALS['registry']->getCharset()); $template->set('jonah', 'Jonah ' . $registry->getVersion() . ' (http://www.horde.org/jonah/)'); @@ -76,13 +81,12 @@ $template->set('channel_official', htmlspecialchars($channel['channel_official'] $template->set('channel_rss', htmlspecialchars(Horde_Util::addParameter(Horde::url('delivery/rss.php', true, -1), array('type' => 'rss', 'channel_id' => $channel['channel_id'])))); $template->set('channel_rss2', htmlspecialchars(Horde_Util::addParameter(Horde::url('delivery/rss.php', true, -1), array('type' => 'rss2', 'channel_id' => $channel['channel_id'])))); foreach ($stories as &$story) { - $story['story_title'] = @htmlspecialchars($story['story_title'], ENT_COMPAT, $GLOBALS['registry']->getCharset()); - $story['story_desc'] = @htmlspecialchars($story['story_desc'], ENT_COMPAT, $GLOBALS['registry']->getCharset()); - $story['story_link'] = htmlspecialchars($story['story_link']); - $story['story_permalink'] = (isset($story['story_permalink']) ? htmlspecialchars($story['story_permalink']) : ''); - $story['story_published'] = htmlspecialchars(date('r', $story['story_published'])); - if (!empty($story['story_body_type']) && $story['story_body_type'] == 'text') { - $story['story_body'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['story_body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); + $story['title'] = @htmlspecialchars($story['title'], ENT_COMPAT, $GLOBALS['registry']->getCharset()); + $story['description'] = @htmlspecialchars($story['description'], ENT_COMPAT, $GLOBALS['registry']->getCharset()); + $story['permalink'] = htmlspecialchars($story['permalink']); + $story['published'] = htmlspecialchars(date('r', $story['published'])); + if (!empty($story['body_type']) && $story['body_type'] == 'text') { + $story['body'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); } } $template->set('stories', $stories); diff --git a/jonah/dispatcher.php b/jonah/dispatcher.php index 49e59f099..2de6623c6 100644 --- a/jonah/dispatcher.php +++ b/jonah/dispatcher.php @@ -8,25 +8,32 @@ * @author Ben Klang */ -require_once dirname(__FILE__) . '/../lib/Application.php'; +require_once dirname(__FILE__) . '/lib/Application.php'; $jonah = Horde_Registry::appInit('jonah', array( 'authentication' => 'none', 'session_control' => 'readonly' )); -$jonah = Horde_Registry::appInit('jonah'); +$m = new Horde_Routes_Mapper(); + +require JONAH_BASE . '/config/routes.php'; require JONAH_BASE . '/config/templates.php'; // Grab, and hopefully match, the URL -$url = Horde_Util::getPathInfo(); -parse_str($_SERVER['QUERY_STRING'], $args); -Horde_Util::dispelMagicQuotes($args); +$request = new Horde_Controller_Request_Http(); +$url = $request->getPath(); + +$args = $request->getGetParams(); +$result = $m->match('/' . $url); $criteria = array(); -$result = $m->match($url); -if (isset($result['controller']) && $result['controller'] == 'admin') { - // Insert admin controllers here. -} elseif (isset($result['feed'])) { +// @TODO: This should be handled by controller objects, but for now just use +// a switch conditional until we move to Horde_Controller +switch ($result['controller']) { +case 'admin': + // TODO: + exit; +case 'feed': // Default settings $defaults = array( 'format' => 'html', @@ -60,6 +67,8 @@ if (isset($result['controller']) && $result['controller'] == 'admin') { break; } + // @TODO: These will be implemented as GData's categories, not as + // part of the route proper. case 'tag': $criteria['tags'] = array($result['value']); break; @@ -145,7 +154,19 @@ if (isset($result['controller']) && $result['controller'] == 'admin') { } // Preserve remaining args + // @TODO: Don't think we need to preserve the query string once we get here. $criteria = array_merge($defaults, $args, $criteria); - - require dirname(__FILE__) . '/feed.php'; + $class = 'Jonah_View_Delivery' . $criteria['format']; + + //@TODO: FIXME - format (html/rss/pdf) is dealt with by the view object we + // instantiate but html _currently_ needs a format. Think we'll just have to + // pick a default format to render when requested this way. + $criteria['format'] = 'standard'; + $params = array('registry' => &$registry, + 'notification' => &$notification, + 'conf' => &$conf, + 'criteria' => &$criteria); + $view = new $class($params); + $view->run(); + break; } diff --git a/jonah/docs/lighttpd-jonah.conf b/jonah/docs/lighttpd-jonah.conf new file mode 100644 index 000000000..059fe4e7f --- /dev/null +++ b/jonah/docs/lighttpd-jonah.conf @@ -0,0 +1,15 @@ +## This file should be reviewed prior to inclusion in your lighttpd +## configuration. Specifically, if you have jonah somewhere other than +## /horde/jonah you will need to edit the following rules to match your server +## configuration. + +## This file should be included in your lighttpd.conf file with the "include" +## directive. Example: +## include "path/to/lighttpd-jonah.conf" +## The exact path you use will of course depend on your specific configuration. + +## Rules for handling restful delivery requests +url.rewrite-once += ( + "^/horde/jonah/feeds/(.*)\?(.*)$" => "/horde/jonah/dispatcher.php?$2", + "^/horde/jonah/feeds/(.*)$" => "/horde/jonah/dispatcher.php" +) \ No newline at end of file diff --git a/jonah/lib/Api.php b/jonah/lib/Api.php index a61f2c6c9..3f25a433f 100644 --- a/jonah/lib/Api.php +++ b/jonah/lib/Api.php @@ -5,6 +5,12 @@ * This file defines Jonah's external API interface. Other * applications can interact with Jonah through this API. * + * Copyright 2002-2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file LICENSE for license information (BSD). If you did not + * did not receive this file, see http://cvs.horde.org/co.php/jonah/LICENSE. + * + * @author Michael J. Rubinsky * @package Jonah */ class Jonah_Api extends Horde_Registry_Api @@ -12,44 +18,47 @@ class Jonah_Api extends Horde_Registry_Api /** * Get a list of stored channels. * - * @param integer $type The type of channel to filter for. Possible - * values are either Jonah::INTERNAL_CHANNEL - * to fetch only a list of internal channels, - * or Jonah::EXTERNAL_CHANNEL for only external. - * If null both channel types are returned. - * - * @return mixed An array of channels or PEAR_Error on error. + * @return array An array of channels */ - public function listFeeds($type = null) + public function listFeeds() { - $news = Jonah_News::factory(); - $channels = $news->getChannels($type); - - return $channels; + return $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannels(); } /** * Return the requested stories * - * @param int $channel_id The channel to get the stories from. - * @param int $max_stories The maximum number of stories to get. - * @param int $start_at The story number to start retrieving. - * @param int $order How to order the results. + * @param integer $channel_id The channel to get the stories from. + * @param array $filter Additional, optional filters. + *
+     *     max_stories  The maximum number of stories to get.
+     *     start_at     The story number to start retrieving.
+     *     order        How to order the results.
+     *   
* - * @return An array of story information | PEAR_Error + * @return array An array of story information */ - public function stories($channel_id, $max_stories = 10, $start_at = 0, - $order = 0) + public function stories($channel_id, $filter = array()) { - $news = Jonah_News::factory(); - $stories = $news->getStories($channel_id, $max_stories, $start_at, false, - time(), false, $order); + $filter = new Horde_Support_Array($filter); + + $stories = $GLOBALS['injector'] + ->getInstance('Jonah_Driver') + ->getStories( + array( + 'channel_id' => $channel_id, + 'limit' => $filter->get('max_stories', 10), + 'startnumber' => $filter->get('start_at', 0), + 'published' => true, + ), + $order + ); foreach (array_keys($stories) as $s) { - if (empty($stories[$s]['story_body_type']) || $stories[$s]['story_body_type'] == 'text') { - $stories[$s]['story_body_html'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($stories[$s]['story_body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); + if (empty($stories[$s]['body_type']) || $stories[$s]['body_type'] == 'text') { + $stories[$s]['body_html'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($stories[$s]['story_body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); } else { - $stories[$s]['story_body_html'] = $stories[$s]['story_body']; + $stories[$s]['body_html'] = $stories[$s]['body']; } } @@ -63,20 +72,15 @@ class Jonah_Api extends Horde_Registry_Api * @param integer $story_id The story id to fetch. * @param boolean $read Whether to update the read count. * - * @return mixed An array of story data | PEAR_Error + * @return array An array of story data */ public function story($channel_id, $story_id, $read = true) { - $news = Jonah_News::factory(); - $story = $news->getStory($channel_id, $story_id, $read); - if (is_a($story, 'PEAR_Error')) { - Horde::logMessage($story, 'ERR'); - return false; - } - if (empty($story['story_body_type']) || $story['story_body_type'] == 'text') { - $story['story_body_html'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['story_body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); + $story = $GLOBALS['injector']->getInstance('Jonah_Driver')->getStory($channel_id, $story_id, $read); + if (empty($story['body_type']) || $story['body_type'] == 'text') { + $story['body_html'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); } else { - $story['story_body_html'] = $story['story_body']; + $story['body_html'] = $story['body']; } return $story; @@ -94,14 +98,9 @@ class Jonah_Api extends Horde_Registry_Api if (!$GLOBALS['conf']['comments']['allow']) { return false; } + $story = $GLOBALS['injector']->getInstance('Jonah_Driver')->getStory(null, $story_id); - $news = Jonah_News::factory(); - $story = $news->getStory(null, $story_id); - if (is_a($story, 'PEAR_Error')) { - return false; - } - - return $story['story_title']; + return $story['title']; } /** @@ -123,12 +122,11 @@ class Jonah_Api extends Horde_Registry_Api * * @param array $channel_id An optional array of channel_ids. * - * @return mixed An array containing tag_name, and total | PEAR_Error + * @return array An array containing tag_name, and total */ public function listTagInfo($tags = array(), $channel_id = null) { - $news = Jonah_News::factory(); - return $news->listTagInfo($tags, $channel_id); + return $GLOBALS['injector']->getInstance('Jonah_Driver')->listTagInfo($tags, $channel_id); } /** @@ -136,46 +134,50 @@ class Jonah_Api extends Horde_Registry_Api * * @param array $names An array of names to search for * - * @return mixed An array of tag_name => tag_ids | PEAR_Error + * @return Array An array of tag_name => tag_ids */ public function getTagIds($names) { - $news = Jonah_News::factory(); - return $news->getTagIds($names); + return $GLOBALS['injector']->getInstance('Jonah_Driver')->getTagIds($names); } /** * Searches internal channels for stories tagged with all requested tags. * Returns an application-agnostic array (useful for when doing a tag search - * across multiple applications) containing the following keys: - *
-     *  'title'    - The title for this resource.
-     *  'desc'     - A terse description of this resource.
-     *  'view_url' - The URL to view this resource.
-     *  'app'      - The Horde application this resource belongs to.
-     * 
+ * across multiple applications). + * * * The 'raw' story array can be returned instead by setting $raw = true. * - * @param array $names An array of tag_names to search for (AND'd together). - * @param integer $max The maximum number of stories to return. - * @param integer $from The number of the story to start with. - * @param array $channel_id An array of channel_ids to limit the search to. - * @param integer $order How to order the results (a Jonah::ORDER_* constant) + * @param array $names An array of tag_names to search for + * (AND'd together). + * @param array $filter An array of optional filter parameters. + *
+     *     max       The maximum number of stories to return.
+     *     from      The number of the story to start with.
+     *     channel_id  An array of channel_ids to limit the search to.
+     *     order     How to order the results (a Jonah::ORDER_* constant)
+     *  
* @param boolean $raw Return the raw story data? * - * @return mixed An array of results | PEAR_Error + * @return An array of results with the following structure: + *
+     *      'title'    - The title for this resource.
+     *      'desc'     - A terse description of this resource.
+     *      'view_url' - The URL to view this resource.
+     *      'app'      - The Horde application this resource belongs to.
+     *    
*/ - public function searchTags($names, $max = 10, $from = 0, $channel_id = array(), - $order = 0, $raw = false) + public function searchTags($names, $filter = array(), $raw = false) { global $registry; - $news = Jonah_News::factory(); - $results = $news->searchTags($names, $max, $from, $channel_id, $order); - if (is_a($results, 'PEAR_Error')) { - return $results; - } + // @TODO: Refactor when moving tag to content_tagger + $filter = new Horde_Support_Array($filter); + $results = $GLOBALS['injector'] + ->getInstance('Jonah_Driver') + ->searchTags($names, $filter->max, $filter->from, $filter->channel_id, $filter->order); + $return = array(); if ($raw) { // Requesting the raw story information as returned from searchTags, @@ -183,26 +185,26 @@ class Jonah_Api extends Horde_Registry_Api // find useful. $comments = $GLOBALS['conf']['comments']['allow'] && $registry->hasMethod('forums/numMessages'); foreach ($results as $story) { - if (empty($story['story_body_type']) || $story['story_body_type'] == 'text') { - $story['story_body_html'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['story_body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); + if (empty($story['body_type']) || $story['body_type'] == 'text') { + $story['body_html'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); } else { - $story['story_body_html'] = $story['story_body']; + $story['body_html'] = $story['body']; } if ($comments) { $story['num_comments'] = $registry->call('forums/numMessages', - array($story['story_id'], + array($story['id'], $registry->getApp())); } - $return[$story['story_id']] = $story; + $return[$story['id']] = $story; } } else { foreach($results as $story) { if (!empty($story)) { - $return[] = array('title' => $story['story_title'], - 'desc' => $story['story_desc'], - 'view_url' => $story['story_link'], + $return[] = array('title' => $story['title'], + 'desc' => $story['desc'], + 'view_url' => $story['link'], 'app' => 'jonah'); } } @@ -219,14 +221,7 @@ class Jonah_Api extends Horde_Registry_Api */ public function storyCount($channel_id) { - global $registry; - - $results = $GLOBALS['injector']->getInstance('Jonah_Driver')->getStoryCount($channel_id); - if (is_a($results, 'PEAR_Error')) { - return 0; - } - - return $results; + return $GLOBALS['injector']->getInstance('Jonah_Driver')->getStoryCount($channel_id); } } diff --git a/jonah/lib/Application.php b/jonah/lib/Application.php index 5a1b09c24..dc1df585d 100644 --- a/jonah/lib/Application.php +++ b/jonah/lib/Application.php @@ -51,31 +51,17 @@ class Jonah_Application extends Horde_Registry_Application 'news' => array( 'title' => _("News") ), - 'news:internal_channels' => array( - 'title' => _("Internal Channels") - ), - 'news:external_channels' => array( - 'title' => _("External Channels") + 'news:channels' => array( + 'title' => _("Channels") ) ); /* Loop through internal channels and add them to the perms * titles. */ - $news = Jonah_News::factory(); - $channels = $news->getChannels(Jonah::INTERNAL_CHANNEL); - - foreach ($channels as $channel) { - $perms['news:internal_channels:' . $channel['channel_id']] = array( - 'title' => $channel['channel_name'] - ); - } - - /* Loop through external channels and add their ids to the - * perms. */ - $channels = $news->getChannels(Jonah::EXTERNAL_CHANNEL); + $channels = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannels(); foreach ($channels as $channel) { - $perms['news:external_channels:' . $channel['channel_id']] = array( + $perms['news:channels:' . $channel['channel_id']] = array( 'title' => $channel['channel_name'] ); } @@ -142,13 +128,16 @@ class Jonah_Application extends Horde_Registry_Application } $url = Horde::url('stories/'); - $news = Jonah_News::factory(); - $channels = $news->getChannels('internal'); - if ($channels instanceof PEAR_Error) { + $driver = $GLOBALS['injector']->getInstance('Jonah_Driver'); + + try { + $channels = $driver->getChannels('internal'); + } catch (Jonah_Exception $e) { + var_dump($e); return; } - $channels = Jonah::checkPermissions('channels', Horde_Perms::SHOW, $channels); + $channels = Jonah::checkPermissions('channels', Horde_Perms::SHOW, $channels); foreach ($channels as $channel) { $tree->addNode( $parent . $channel['channel_id'], diff --git a/jonah/lib/Block/cloud.php b/jonah/lib/Block/cloud.php index d00acb67e..a3f6ae48e 100644 --- a/jonah/lib/Block/cloud.php +++ b/jonah/lib/Block/cloud.php @@ -21,11 +21,8 @@ class Horde_Block_jonah_cloud extends Horde_Block { */ function _params() { - return array( - 'results_url' => array( - 'name' => _("Results URL"), - 'type' => 'text', - 'default' => Horde::url('stories/results.php?tag_id=@id@'))); + return array(); + } function _title() @@ -35,19 +32,19 @@ class Horde_Block_jonah_cloud extends Horde_Block { function _content() { - $news = Jonah_News::factory(); - /* Get the tags */ - $tags = $news->listTagInfo(); + $tags = $GLOBALS['injector']->getInstance('Jonah_Driver')->listTagInfo(); if (count($tags)) { - $cloud = new Horde_Core_Ui_TagCloud(); + $url = Horde::url('stories/results.php'); + $cloud = new Horde_Ui_TagCloud(); foreach ($tags as $id => $tag) { - $cloud->addElement($tag['tag_name'], str_replace(array('@id@', '@tag@'), array($id, $tag['tag_name']), $this->_params['results_url']), $tag['total']); + $cloud->addElement($tag['tag_name'], $url->copy()->add('tag_id', $id), $tag['total']); } $html = $cloud->buildHTML(); } else { $html = ''; } + return $html; } diff --git a/jonah/lib/Block/delivery.php b/jonah/lib/Block/delivery.php index 7208340a3..57371d13e 100644 --- a/jonah/lib/Block/delivery.php +++ b/jonah/lib/Block/delivery.php @@ -6,7 +6,7 @@ $block_name = _("Feeds"); * This class extends Horde_Block:: to provide a list of deliverable internal * channels. * - * Copyright 2004-2009 The Horde Project (http://www.horde.org/) + * Copyright 2004-2010 The Horde Project (http://www.horde.org/) * * See the enclosed file LICENSE for license information (BSD). If you * did not receive this file, see http://cvs.horde.org/co.php/jonah/LICENSE. diff --git a/jonah/lib/Block/latest.php b/jonah/lib/Block/latest.php index 24257105e..beae9b77c 100644 --- a/jonah/lib/Block/latest.php +++ b/jonah/lib/Block/latest.php @@ -6,18 +6,17 @@ $block_name = _("Latest News"); * This class extends Horde_Block:: to provide the api to embed news * in other Horde applications. * - * Copyright 2002-2007 Roel Gloudemans + * Copyright 2002-2010 Roel Gloudemans * * See the enclosed file LICENSE for license information (BSD). If you * did not receive this file, see http://cvs.horde.org/co.php/jonah/LICENSE. * * @author Roel Gloudemans - * @package Horde_Block + * @package Jonah */ -class Horde_Block_Jonah_latest extends Horde_Block { - +class Horde_Block_Jonah_latest extends Horde_Block +{ var $_app = 'jonah'; - var $_story = null; /** @@ -28,8 +27,7 @@ class Horde_Block_Jonah_latest extends Horde_Block { 'type' => 'enum', 'values' => array()); - $news = Jonah_News::factory(); - $channels = $news->getChannels(Jonah::INTERNAL_CHANNEL); + $channels = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannels(); foreach ($channels as $channel) { $params['source']['values'][$channel['channel_id']] = $channel['channel_name']; } @@ -55,13 +53,16 @@ class Horde_Block_Jonah_latest extends Horde_Block { return _("Latest News"); } - $story = $this->_fetch(); - return is_a($story, 'PEAR_Error') - ? @htmlspecialchars($story->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()) - : ' ' - . @htmlspecialchars($story['story_title'], ENT_COMPAT, $GLOBALS['registry']->getCharset()); + try { + $story = $this->_fetch(); + } catch (Exception $e) { + return @htmlspecialchars($e->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()); + } + + return ' ' + . @htmlspecialchars($story['title'], ENT_COMPAT, $GLOBALS['registry']->getCharset()); } /** @@ -72,17 +73,17 @@ class Horde_Block_Jonah_latest extends Horde_Block { return _("No channel specified."); } - $story = $this->_fetch(); - if (is_a($story, 'PEAR_Error')) { - return sprintf(_("Error fetching story: %s"), $story->getMessage()); + try { + $story = $this->_fetch(); + } catch (Exception $e) { + return sprintf(_("Error fetching story: %s"), $e->getMessage()); } - if (empty($story['story_body_type']) || $story['story_body_type'] == 'text') { - $story['story_body'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['story_body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); + if (empty($story['body_type']) || $story['body_type'] == 'text') { + $story['body'] = $GLOBALS['injector']->getInstance('Horde_Text_Filter')->filter($story['body'], 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); } - return '

' . htmlspecialchars($story['story_desc']) . - '

' . $story['story_body'] . '
'; + return '

' . htmlspecialchars($story['description']) . '

' . $story['body'] . '
'; } /** @@ -95,9 +96,9 @@ class Horde_Block_Jonah_latest extends Horde_Block { } if (is_null($this->_story)) { - $news = Jonah_News::factory(); - $this->_story = $news->getStory($this->_params['source'], - $news->getLatestStoryId($this->_params['source']), + $driver = $GLOBALS['injector']->getInstance('Jonah_Driver'); + $this->_story = $driver->getStory($this->_params['source'], + $driver->getLatestStoryId($this->_params['source']), !empty($this->_params['countReads'])); } diff --git a/jonah/lib/Block/news.php b/jonah/lib/Block/news.php index 4bd45c543..744db8ba8 100644 --- a/jonah/lib/Block/news.php +++ b/jonah/lib/Block/news.php @@ -27,8 +27,7 @@ class Horde_Block_Jonah_news extends Horde_Block { 'type' => 'enum', 'values' => array()); - $news = Jonah_News::factory(); - $channels = $news->getChannels(); + $channels = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannels(); foreach ($channels as $channel) { $params['source']['values'][$channel['channel_id']] = $channel['channel_name']; } @@ -57,10 +56,10 @@ class Horde_Block_Jonah_news extends Horde_Block { function _title() { - $news = Jonah_News::factory(); - $channel = $news->getChannel($this->_params['source']); - if (is_a($channel, 'PEAR_Error')) { - return @htmlspecialchars($channel->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()); + try { + $channel = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannel($this->_params['source']); + } catch (Jonah_Exception $e) { + return @htmlspecialchars($e->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()); } if (!empty($channel['channel_link'])) { @@ -80,18 +79,13 @@ class Horde_Block_Jonah_news extends Horde_Block { return _("No feed specified."); } - $news = Jonah_News::factory(); - $params = $this->_params(); - $view = isset($this->_params['view']) ? $this->_params['view'] : 'standard'; - if (!isset($this->_params['max'])) { - $this->_params['max'] = $params['max']['default']; - } - if (!isset($this->_params['from'])) { - $this->_params['from'] = $params['from']['default']; - } - return $news->renderChannel($this->_params['source'], $view, $this->_params['max'], $this->_params['from']); + return $GLOBALS['injector']->getInstance('Jonah_Driver')->renderChannel( + $this->_params['source'], + $view, + $this->_params['max'], + $this->_params['from']); } } diff --git a/jonah/lib/Block/news_popular.php b/jonah/lib/Block/news_popular.php index 0c34b8074..87db9351f 100644 --- a/jonah/lib/Block/news_popular.php +++ b/jonah/lib/Block/news_popular.php @@ -28,8 +28,7 @@ class Horde_Block_Jonah_news_popular extends Horde_Block { 'type' => 'enum', 'values' => array()); - $news = Jonah_News::factory(); - $channels = $news->getChannels(); + $channels = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannels(); foreach ($channels as $channel) { if ($channel['channel_type'] == Jonah::INTERNAL_CHANNEL) { $params['source']['values'][$channel['channel_id']] = $channel['channel_name']; @@ -54,10 +53,10 @@ class Horde_Block_Jonah_news_popular extends Horde_Block { function _title() { - $news = Jonah_News::factory(); - $channel = $news->getChannel($this->_params['source']); - if (is_a($channel, 'PEAR_Error')) { - return @htmlspecialchars($channel->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()); + try { + $channel = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannel($this->_params['source']); + } catch (Exception $e) { + return @htmlspecialchars($e->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()); } if (!empty($channel['channel_link'])) { @@ -78,7 +77,6 @@ class Horde_Block_Jonah_news_popular extends Horde_Block { return _("No feed specified."); } - $news = Jonah_News::factory(); $params = $this->_params(); $view = isset($this->_params['view']) ? $this->_params['view'] : 'standard'; @@ -87,7 +85,7 @@ class Horde_Block_Jonah_news_popular extends Horde_Block { } - return $news->renderChannel($this->_params['source'], $view, $this->_params['max'], 0, Jonah::ORDER_READ); + return $GLOBALS['injector']->getInstance('Jonah_Driver')->renderChannel($this->_params['source'], $view, $this->_params['max'], 0, Jonah::ORDER_READ); } } diff --git a/jonah/lib/Block/story.php b/jonah/lib/Block/story.php index 9c3d66fad..093a4a158 100644 --- a/jonah/lib/Block/story.php +++ b/jonah/lib/Block/story.php @@ -24,8 +24,7 @@ class Horde_Block_Jonah_story extends Horde_Block { */ function _params() { - $news = Jonah_News::factory(); - $channels = $news->getChannels(Jonah::INTERNAL_CHANNEL); + $channels = $GLOBALS['injector']->getInstance('Jonah_Driver')->getChannels(); $channel_choices = array(); foreach ($channels as $channel) { $channel_choices[$channel['channel_id']] = $channel['channel_name']; @@ -55,13 +54,15 @@ class Horde_Block_Jonah_story extends Horde_Block { return _("Story"); } - $story = $this->_fetch(); - return is_a($story, 'PEAR_Error') - ? @htmlspecialchars($story->getMessage(), ENT_COMPAT, $GLOBALS['registry']->getCharset()) - : '