/** * Get a instance for a unique id and feed * * @param RDR_Feed $feed * @param mixed $uniqueId * @return self */ static function get(RDR_Feed $feed, $uniqueId) { $uniqueId = $feed->getId() . "-" . md5($uniqueId); $object = RDR_Entry::getByCondition("uniqueId = {1}", array($feed, $uniqueId)); if ($object) { return reset($object); } $object = new self(db()); $object->feed = $feed; $object->uniqueId = $uniqueId; return $object; }
/** * Cleanup unused feeds */ static function cleanupFeeds() { $feeds = RDR_Feed::getByQuery("\n SELECT t0.id FROM RDR_Feed as t0\n LEFT JOIN RDR_Category_feeds as t1 ON t1.v = t0.id\n WHERE t1.id IS null\n "); if ($feeds) { db()->deleteMultiple($feeds); } }
/** * Get a instance for a url * * @param string $url * @return self */ static function get($url) { $object = RDR_Feed::getByCondition("url = {0}", array($url)); if ($object) { return reset($object); } $object = new self(db()); $object->url = $url; return $object; }
/** * Import new feed from url * * @param mixed $url * @param RDR_Category $category * @return RDR_Event The last event for that import */ static function addFeed($url, RDR_Category $category) { $feed = RDR_Feed::get($url); if ($feed->getId()) { $categories = user()->getCategories(); $feedExist = false; foreach ($categories as $category) { if ($category->getByKey("feeds", $feed->getId())) { $feedExist = true; break; } } if (!$feedExist) { $category->add("feeds", $feed); $category->store(); return RDR_Event::log(RDR_Event::TYPE_FEED_ADD_OK, array("feed" => $feed)); } return RDR_Event::log(RDR_Event::TYPE_FEED_EXIST, array("text" => $url)); } $xml = self::getSimpleXMLFromUrl($feed->url); if (!$xml) { return RDR_Event::$lastEvent; } $title = ""; $tmp = $xml->xpath("/rss/channel/title"); if ($tmp) { $title = self::xmlValue($tmp); } if (!$title) { $tmp = $xml->title; if ($tmp) { $title = self::xmlValue($tmp); } } if (!$title) { $tmp = $xml->channel && $xml->channel->title ? $xml->channel->title : null; if ($tmp) { $title = self::xmlValue($tmp); } } if (!$title) { return RDR_Event::log(RDR_Event::TYPE_MISSING_PARSER, array("text" => $url . ":title")); } $feed->name = trim($title); $feed->store(); $category->add("feeds", $feed); $category->store(); return RDR_Event::log(RDR_Event::TYPE_FEED_ADD_OK, array("feed" => $feed)); }
/** * Load the View */ public function onLoad() { if (!needRole()) { return; } $jsonData = null; switch (post("action")) { case "delete-feed-user": $feed = RDR_Feed::getById(post("data[fid]")); if ($feed) { $cats = user()->getCategories(); foreach ($cats as $category) { $feeds = $category->feeds; if ($feeds) { foreach ($feeds as $key => $catFeed) { if (compare($catFeed, $feed)) { unset($feeds[$key]); } } if (count($feeds) != count($category->feeds)) { $category->feeds = $feeds; $category->store(); } } } } break; case "delete-feed-admin": if (needRole(RDR_User::ROLE_ADMIN)) { $feed = RDR_Feed::getById(post("data[fid]")); if ($feed) { $feed->delete(); } } break; case "add-feed": $event = RDR_Import::addFeed(post("data[url]"), RDR_Category::get(post("data[category]"))); if ($event->feed) { RDR_Import::importFeedEntries($event->feed); } break; case "mark-all-as-readed": $cache = session("entry.ids.original"); if ($cache) { $ids = array_keys($cache); user()->loadReadedFlags(array_keys($ids)); $insertIds = array(); foreach ($ids as $id) { if (!isset(user()->_cacheReaded[$id])) { $insertIds[$id] = $id; } } if ($insertIds) { $query = "INSERT IGNORE INTO RDR_User_readed (o,k,v) VALUES "; foreach ($insertIds as $id) { $query .= " (" . user()->getId() . ", {$id}, 1), "; } $query = substr($query, 0, -2); db()->query($query); user()->updateReadedCount(); } } break; case "update-setting-user": user()->setting(post("data[key]"), post("data[value]")); user()->store(); break; case "update-newscache": user()->updateNewsCache(); $jsonData = user()->getAjaxData(); break; case "set-entries-readed": if (post("data[ids]")) { $entries = RDR_Entry::getByIds(post("data[ids]")); if ($entries) { user()->loadReadedFlags(array_keys($entries)); $insertIds = $deleteIds = array(); foreach ($entries as $entry) { $id = $entry->getId(); if ($id < user()->setting("init.entry")) { continue; } if (isset(user()->_cacheReaded[$id])) { $deleteIds[$id] = $id; } else { $insertIds[$id] = $id; } } if ($insertIds) { $query = "INSERT IGNORE INTO RDR_User_readed (o,k,v) VALUES "; foreach ($insertIds as $id) { $query .= " (" . user()->getId() . ", {$id}, 1), "; } $query = substr($query, 0, -2); db()->query($query); } if ($deleteIds) { $query = "DELETE FROM RDR_User_readed WHERE o = " . user()->getId() . " && k IN " . db()->toDb($deleteIds); } user()->updateReadedCount(); } } break; case "set-entries-saved": if (post("data[ids]")) { $entry = RDR_Entry::getById(post("data[ids][0]")); if ($entry) { if (user()->getByKey("saved", $entry->getId())) { user()->remove("saved", $entry->getId()); } else { user()->add("saved", 1, $entry->getId()); } user()->store(); } } break; case "set-feed-property": if (needRole(RDR_User::ROLE_ADMIN)) { $feed = RDR_Feed::getById(post("data[feed]")); if ($feed) { $feed->{post("data[field]")} = post("data[value]"); $feed->store(); } } break; } echo json_encode($jsonData, JSON_FORCE_OBJECT); }
/** * Load the View */ public function onLoad() { if (!needRole()) { return; } # some ajax actions switch (post("action")) { case "admin-feed": if (needRole(RDR_User::ROLE_ADMIN)) { $entry = RDR_Entry::getById(post("eid")); $feed = RDR_Feed::getById(post("fid")); ?> <b><?php echo t("feedadmin.raw.1"); ?> </b> <div class="small"> <?php echo t("feedadmin.raw.2"); ?> </div> <code class="raw"><?php echo s('<div>' . $entry->text . '</div>'); ?> </code><br/><br/> <b><?php echo t("feedadmin.format.1"); ?> </b> <div class="small"> <?php echo t("feedadmin.format.2"); ?> </div> <code class="formated"></code><br/><br/> <b><?php echo sprintf(t("feedadmin.js.1"), s(cut($feed->name, 30))); ?> </b> <div class="small"> <?php echo nl2br(sprintf(t("feedadmin.js.2"), s('<p>'), 'html = $(html); html.find("p").remove()')); ?> <br/> <textarea data-field="contentJS" style="width:90%" cols="45" rows="3"><?php echo s($feed->contentJS); ?> </textarea> </div> <?php } return; break; case "readed": if (post("ids")) { $entries = RDR_Entry::getByIds(post("ids")); if ($entries) { user()->loadReadedFlags(array_keys($entries)); $insertIds = $deleteIds = array(); foreach ($entries as $entry) { $id = $entry->getId(); if ($id < user()->setting("init.entry")) { continue; } if (isset(user()->_cacheReaded[$id])) { $deleteIds[$id] = $id; } else { $insertIds[$id] = $id; } } if ($insertIds) { $query = "INSERT IGNORE INTO RDR_User_readed (o,k,v) VALUES "; foreach ($insertIds as $id) { $query .= " (" . user()->getId() . ", {$id}, 1), "; } $query = substr($query, 0, -2); db()->query($query); } if ($deleteIds) { $query = "DELETE FROM RDR_User_readed WHERE o = " . user()->getId() . " && k IN " . db()->toDb($deleteIds); } user()->updateReadedCount(); } } break; case "saved": if (post("ids")) { $entry = RDR_Entry::getById(post("ids[0]")); if ($entry) { if (user()->getByKey("saved", $entry->getId())) { user()->remove("saved", $entry->getId()); } else { user()->add("saved", 1, $entry->getId()); } user()->store(); } } break; } $jsonData = user()->getAjaxData(); echo json_encode($jsonData, JSON_FORCE_OBJECT); }
/** * Get content */ public function getContent() { headline(t("admin.update.cron.title")); ?> <div class="indent"> <?php echo nl2br(t("admin.update.cron.text")); ?> <br/> <code style="font-size: 11px;">*/10 * * * * php -f <?php echo escapeshellarg(CHOQ_ROOT_DIRECTORY . DIRECTORY_SEPARATOR . "console.php"); ?> <?php echo escapeshellarg("cron"); ?> </code> </div> <div class="spacer"></div> <?php headline(t("admin.update.webcron.title")); ?> <div class="indent"> <?php echo nl2br(t("admin.update.webcron.text")); ?> <br/> <code style="font-size: 11px;"><a href="<?php echo RDR_Cron::getLink(); ?> " target="_blank"><?php echo RDR_Cron::getLink(); ?> </a></code> </div> <div class="spacer"></div> <?php headline(t("admin.update.3")); ?> <div class="indent"> <?php echo t("admin.update.4"); ?> .<br/><br/> <div class="btn update-all"><?php echo t("admin.update.5"); ?> </div> <div class="spacer"></div> <?php $feeds = RDR_Feed::getByCondition(null, null, "+name"); foreach ($feeds as $feed) { ?> <div style="padding-left: 20px; margin-bottom: 2px;" class="feed"> <div class="inline-btn update-feed" data-id="<?php echo $feed->getId(); ?> "><?php echo t("admin.update.6"); ?> </div> <div class="inline-btn delete-feed" data-id="<?php echo $feed->getId(); ?> "><?php echo t("organize.15"); ?> </div> <img src="<?php echo url()->getByAlias("public", "img/loading-2.gif"); ?> " alt="" style="position: relative; top:2px; display: none;" class="loading-feed"/> <a href="<?php echo $feed->getLink(); ?> "><?php echo s($feed->name); ?> </a><br/> <div class="small" style="margin-top:3px;"><a href="<?php echo s($feed->url); ?> "><?php echo s($feed->url); ?> </a></div> </div> <?php } ?> </div> <script type="text/javascript"> (function(){ $("#content div.update-feed.inline-btn").on("click", function(){ $("img.loading-feed").hide(); pipeline = [$(this).attr("data-id")]; runUpdate(); }); $("#content div.delete-feed.inline-btn").on("click", function(){ if(confirm(<?php echo json_encode(t("organize.13")); ?> )){ API.req("delete-feed-admin", {"fid" : $(this).attr("data-id")}); $(this).closest(".feed").remove(); } }); $("#content div.update-all").on("click", function(){ $("#content img.loading-feed").hide(); pipeline = []; $("#content div.update-feed.inline-btn").each(function(){ pipeline.push($(this).attr("data-id")); }); runUpdate(); }); var pipeline = []; function runUpdate(){ if(!pipeline.length) { Global.updateNewsCache(); return; } var id = pipeline.shift(); var btn = $("#content div.update-feed[data-id='"+id+"']").parent().find(".loading-feed"); btn.show(); $.post('<?php echo url()->getUri(); ?> ', {"update" : id}, function(){ btn.hide(); runUpdate(); }); } })(); </script> <?php }
/** * Get the users category to the feed * * @param RDR_Feed $feed * @return RDR_Category | null */ public function getCategoryToFeed(RDR_Feed $feed) { $categories = $this->getCategories(); if (!$categories) { return; } foreach ($categories as $category) { $tmp = $category->feeds; if ($tmp) { foreach ($tmp as $f) { if ($f->getId() == $feed->getId()) { return $category; } } } } }
/** * Load the View */ public function onLoad() { needRole(null, true); $p = $this->getParam("param"); $explodeParam = explode("-", $p); $pType = arrayValue($explodeParam, 0); $pVal = arrayValue($explodeParam, 1); $title = t("sidebar.10"); $categories = user()->getCategories(); $feeds = user()->getFeeds(); switch ($pType) { case "cat": if (isset($categories[$pVal])) { $this->category = $categories[$pVal]; $title = $this->category->name; $feeds = $this->category->feeds; if (isset($exp[1]) && isset($feeds[$exp[1]])) { $this->feed = $feeds[$exp[1]]; $title = $this->feed->name; } } break; case "feed": if (isset($feeds[$pVal])) { $this->feed = $feeds[$pVal]; $this->category = user()->getCategoryToFeed($this->feed); $title = $this->feed->getCustomName($this->category); } elseif (needRole(RDR_User::ROLE_ADMIN)) { $this->feed = RDR_Feed::getById($pVal); if ($this->feed) { $this->feed = $feeds[$pVal]; $title = $this->feed->name; } } break; case "search": $this->readedLayoutEnabled = false; $title = sprintf(t("feeds.1"), s(get("q"))); break; case "archive": $this->readedLayoutEnabled = false; $title = t("archive.title"); break; case "saved": $this->readedLayoutEnabled = false; $title = t("sidebar.11"); break; } if (req()->isAjax()) { # fetch all html to pass it to the json output ob_start(); if (!post("requestCounter")) { $hasUnreaded = false; $cache = session("entry.cache"); if (!$categories) { $ids = array(); } elseif ($pType == "search") { $feeds = user()->getFeeds(); $query = "\n SELECT t0.id\n FROM RDR_Entry as t0\n WHERE t0.feed IN " . db()->toDb($feeds) . " && t0.title LIKE " . db()->toDb("%" . get("q") . "%") . "\n ORDER BY datetime DESC\n "; $ids = db()->fetchColumn($query); } elseif ($pType == "archive") { $feeds = user()->getFeeds(); $condition = "1 "; if (get("from") && dt(get("from"))->valid) { $condition .= " && t0.datetime >= " . db()->toDb(dt(get("from"))->getSQLDate()); } if (get("to") && dt(get("to"))->valid) { $condition .= " && t0.datetime <= " . db()->toDb(dt(get("to"))->getSQLDate()); } $query = "\n SELECT t0.id\n FROM RDR_Entry as t0\n WHERE t0.feed IN " . db()->toDb($feeds) . " && {$condition}\n ORDER BY datetime DESC\n "; $ids = db()->fetchColumn($query); } elseif ($pType == "saved") { $ids = user()->saved; if ($ids) { $ids = array_keys($ids); } if (!$ids) { $ids = array(); } } else { $ids = array(); if ($cache) { user()->loadReadedFlags(array_keys($cache)); foreach ($cache as $id => $row) { # if already readed than hide the entry if (isset(user()->_cacheReaded[$id])) { continue; } # feed mode if ($this->feed) { if ($row["feed"] == $this->feed->getId()) { $ids[$id] = $id; } continue; } # category mode if ($this->category) { if ($row["category"] == $this->category->getId()) { $ids[$id] = $id; } continue; } # all mode $ids[$id] = $id; } } } # load readed flags only if required if ($this->readedLayoutEnabled) { user()->loadReadedFlags($ids); } # if view all and no article exist, update init entry to latest read id if ($pType == "all" && !$ids) { if ($feeds) { $id = db()->fetchOne("\n SELECT MAX(CAST(t0.k as signed))\n FROM RDR_User_readed as t0\n WHERE t0.o = " . user()->getId() . "\n "); user()->updateInitEntry($id); user()->updateNewsCache(); user()->readed = null; user()->store(); } } session("entry.ids", $ids); session("entry.ids.original", $ids); } $max = RDR_Entry::ENTRIES_PER_PAGE; $ids = session("entry.ids"); if (!$ids) { $ids = array(); } $entryIds = array_slice($ids, 0, $max); session("entry.ids", array_slice($ids, $max)); $entries = RDR_Entry::getByIds($entryIds, true); foreach ($entries as $entry) { $this->displayEntry($entry); } $c = count($entries); if ($c == $max) { ?> <div id="feed-view-trigger"></div> <?php } else { ?> <div class="feeds-footer"> <div style="display: none;"><input type="button" value="<?php echo t("mark.all.category"); ?> " class="btn" id="all-read-btn"/></div> <?php echo t("end.newssection.1"); ?> <br/> <div class="small"><?php echo t("end.newssection.2"); ?> </div> </div> <?php } $jsonData = user()->getAjaxData(); $jsonData["count"] = count(session("entry.ids.original")); if ($pType == "archive") { $jsonData["archive"] = count($ids); } $jsonData["content"] = ob_get_contents(); ob_end_clean(); echo json_encode($jsonData); return; } $this->parameters["title"] = $title; view("RDR_BasicFrame", array("view" => $this)); }