PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/bx/streams/blog.php

https://github.com/chregu/fluxcms
PHP | 860 lines | 559 code | 96 blank | 205 comment | 104 complexity | 0646efebb071a027ff406fdcfc1c2c17 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. class bx_streams_blog extends bx_streams_buffer {
  3. static $tablePrefixes = array();
  4. static $adminPlugins = array(
  5. "plazes",
  6. "geoloc"
  7. );
  8. private $tidyOptions = array(
  9. "output-xhtml" => true,
  10. "show-body-only" => true,
  11. "clean" => true,
  12. "wrap" => "350",
  13. "indent" => true,
  14. "indent-spaces" => 1,
  15. "ascii-chars" => false,
  16. "wrap-attributes" => false,
  17. "alt-text" => "",
  18. "doctype" => "loose",
  19. "numeric-entities" => true,
  20. "drop-proprietary-attributes" => true
  21. );
  22. private $zeroDate = "0000-00-00 00:00:00";
  23. function contentOnRead($path) {
  24. $parts = bx_collections::getCollectionAndFileParts($path, "output");
  25. $p = $parts['coll']->getFirstPluginMapByRequest("index", "html");
  26. $p = $p['plugin'];
  27. $colluri = $parts['coll']->uri;
  28. $this->tablePrefix = $GLOBALS['POOL']->config->getTablePrefix() . $p->getParameter($colluri, "tableprefix");
  29. if ($pos = strpos($parts["name"], "(")) {
  30. $pos2 = strpos($parts["name"], ")");
  31. $params = substr($parts["name"], $pos + 1, $pos2 - $pos - 1);
  32. $parts["name"] = substr($parts["name"], 0, $pos);
  33. $params = explode(",", $params);
  34. }
  35. $pos = strpos($parts["name"], "/");
  36. $appendPostComments = FALSE;
  37. if ($parts['ext'] == "xml" && $pos === false) {
  38. $section = $parts["name"];
  39. $name = "";
  40. } else if ($pos > 0) {
  41. $section = substr($parts["name"], 0, $pos);
  42. $name = substr($parts["name"], $pos + 1, 0);
  43. } else {
  44. $section = "";
  45. $name = $parts["name"];
  46. }
  47. switch ($section) {
  48. case "categories" :
  49. return $this->returnCategories();
  50. case "entries" :
  51. if (isset($params) && isset($params[0])) {
  52. $p->maxPosts = $params[0];
  53. } else {
  54. $p->maxPosts = 10;
  55. }
  56. $xml = $p->getContentById("$colluri", "_all/index");
  57. $xsl = new DomDocument();
  58. $xsl->load(BX_LIBS_DIR . "/streams/blog/html2feed.xsl");
  59. break;
  60. case "entriesfull" :
  61. if (isset($params) && isset($params[0])) {
  62. $p->maxPosts = $params[0];
  63. } else {
  64. $p->maxPosts = 10;
  65. }
  66. $xml = $p->getContentById("$colluri", "_all/index");
  67. $xsl = new DomDocument();
  68. $xsl->load(BX_LIBS_DIR . "/streams/blog/html2feedfull.xsl");
  69. break;
  70. case "storage" :
  71. return file_get_contents(BX_DATA_DIR . $colluri . 'storage.xml');
  72. break;
  73. default :
  74. try {
  75. $xml = $p->getContentById("$colluri", $parts["name"]);
  76. $appendPostComments = TRUE;
  77. } catch (BxPageNotFoundException $e) {
  78. $xml = new DomDocument();
  79. $xml->load(BX_LIBS_DIR . "/streams/blog/newentry.xml");
  80. //FIXME: Abfrage nach storage.xml
  81. if (file_exists(BX_DATA_DIR . "blog/storage.xml") && $section != 'storage') {
  82. $filetime = date("F d Y H:i:s.", filemtime(BX_DATA_DIR . "blog/storage.xml"));
  83. $fileString = file_get_contents(BX_DATA_DIR . "blog/storage.xml");
  84. preg_match('#<title>(.*)</title>#', $fileString, $matches);
  85. $xml->documentElement->setAttribute("hasStorage", "true");
  86. $xml->documentElement->setAttribute("storageDate", $filetime);
  87. $xml->documentElement->setAttribute("storageTitle", $matches['1']);
  88. }
  89. $xp = new DomXPath($xml);
  90. $res = $xp->query("/atom:entry/atom:author/atom:name/text()");
  91. if ($res->length > 0) {
  92. try {
  93. $res->item(0)->data = bx_permm::getInstance()->getUsername();
  94. } catch (Exception $e) {
  95. $res->item(0)->data = '';
  96. }
  97. }
  98. if (isset($_GET['link_title'])) {
  99. $res = $xp->query("/atom:entry/atom:title");
  100. $res->item(0)->appendChild($xml->createTextNode(($_GET['link_title'])));
  101. $res = $xp->query("/atom:entry/atom:uri");
  102. $res->item(0)->appendChild($xml->createTextNode(bx_helpers_string::makeUri(bx_helpers_globals::stripMagicQuotes($_GET['link_title']))));
  103. }
  104. if (isset($_GET['text'])) {
  105. $res = $xp->query("/atom:entry/atom:content");
  106. $html = "<foo><blockquote>" . nl2br(htmlspecialchars(bx_helpers_globals::stripMagicQuotes($_GET['text']))) . "</blockquote>";
  107. if (isset($_GET['link_href'])) {
  108. $html .= '<p>From <a href="' . htmlspecialchars(bx_helpers_globals::stripMagicQuotes($_GET['link_href'])) . '">' . htmlspecialchars(bx_helpers_globals::stripMagicQuotes($_GET['link_title'])) . '</a></p>';
  109. }
  110. $html .= "</foo>";
  111. $domi = new domdocument();
  112. $domi->loadXML($html);
  113. foreach ($domi->documentElement->childNodes as $node) {
  114. $res->item(0)->appendChild($xml->importNode($node, true));
  115. }
  116. }
  117. return $xml->saveXML();
  118. }
  119. $xsl = new DomDocument();
  120. $xsl->load(BX_LIBS_DIR . "/streams/blog/html2xml.xsl");
  121. }
  122. $proc = new XSltProcessor();
  123. $proc->importStylesheet($xsl);
  124. $proc->setParameter("", "webroot", BX_WEBROOT);
  125. //FIXME Abfrage
  126. if (file_exists(BX_DATA_DIR . "blog/storage.xml") && $section != 'storage') {
  127. $proc->setParameter("", "hasStorage", 'true');
  128. }
  129. $proc->setParameter("", "colluri", $colluri);
  130. $xml = $proc->transformToDoc($xml);
  131. // append latest comments to generated feed xml when we are in overview mode
  132. if ($section == 'entries') {
  133. $latestCommentsXML = $p->getContentByID("$colluri", 'plugin=comments(latest).xml');
  134. $latestCommentsNode = $xml->importNode($latestCommentsXML->documentElement, TRUE);
  135. $new = $xml->documentElement->appendChild($latestCommentsNode);
  136. if ($new instanceof DOMElement) {
  137. $new->setAttribute("status", "1");
  138. }
  139. $latestCommentsXML = $p->getContentByID("$colluri", 'plugin=comments(latest,2).xml');
  140. $latestCommentsNode = $xml->importNode($latestCommentsXML->documentElement, TRUE);
  141. $new = $xml->documentElement->appendChild($latestCommentsNode);
  142. if ($new instanceof DOMElement) {
  143. $new->setAttribute("status", "2");
  144. }
  145. $latestCommentsXML = $p->getContentByID("$colluri", 'plugin=comments(latest,3).xml');
  146. $latestCommentsNode = $xml->importNode($latestCommentsXML->documentElement, TRUE);
  147. $new = $xml->documentElement->appendChild($latestCommentsNode);
  148. if ($new instanceof DOMElement) {
  149. $new->setAttribute("status", "3");
  150. }
  151. } else if ($appendPostComments === TRUE) {
  152. // append all comments of a post when viewing an existing entry
  153. $idNS = $xml->documentElement->getElementsByTagName('id');
  154. $entryID = $idNS->item(0)->nodeValue;
  155. $commentsXML = $p->getContentByID($colluri, 'plugin=comments(' . $entryID . ',0).xml');
  156. $commentsNode = $xml->importNode($commentsXML->documentElement, TRUE);
  157. $xml->documentElement->appendChild($commentsNode);
  158. }
  159. return $xml->saveXML();
  160. }
  161. function getAttrib($name) {
  162. return $this->getParameter($name);
  163. }
  164. function stream_close() {
  165. $this->tablePrefix = self::getTablePrefix($this->path);
  166. if ($this->mode == 'w') {
  167. $parts = bx_collections::getCollectionAndFileParts($this->path, "output");
  168. $p = $parts['coll']->getFirstPluginMapByRequest("index", "html");
  169. $p = $p['plugin'];
  170. $colluri = $parts['coll']->uri;
  171. $blogid = $p->getParameter($colluri, "blogid");
  172. $content = $this->html;
  173. $content = preg_replace('/(\.\.\/+)+files/', BX_WEBROOT . 'files', $content);
  174. $this->dom = new DomDocument();
  175. if (!$this->dom->loadXML($content)) {
  176. // try fixing html entities
  177. $content = html_entity_decode(str_replace("&amp;", "&amp;amp;", $content), ENT_NOQUOTES, "UTF-8");
  178. // and set evil recover to true (5.1 only)
  179. $this->dom->recover = true;
  180. if (!$this->dom->loadXML($content)) {
  181. print "<font color='red'>Couldn't save. Invalid XML Document....</font>";
  182. return false;
  183. }
  184. }
  185. $this->xp = new domxpath($this->dom);
  186. $this->xp->registerNamespace("atom", "http://purl.org/atom/ns#");
  187. $this->xp->registerNamespace("xhtml", "http://www.w3.org/1999/xhtml");
  188. $this->xp->registerNamespace("dc", "http://purl.org/dc/elements/1.1/");
  189. $id = $this->getElement("id");
  190. /*if ($this->path != '/'.$id.'.html') {
  191. $this->deleteEntry(substr($path,1,-5));
  192. }*/
  193. if ($id) {
  194. $this->updateEntry($id);
  195. } else {
  196. $this->insertEntry();
  197. }
  198. }
  199. return true;
  200. }
  201. function deleteEntry($id) {
  202. $query = "delete from " . $this->tablePrefix . "blogposts where post_uri = '$id'";
  203. $GLOBALS['POOL']->dbwrite->query("$query");
  204. }
  205. function fixDate($date, $defNow = true) {
  206. if ((!$date || $date == "now()" || $date == $this->zeroDate)) {
  207. return ($defNow == true) ? gmdate("Y-m-d H:i:s", time()) : $this->zeroDate;
  208. }
  209. if (strpos($date, "Z") === false && strpos($date, "+") === false && strpos($date, "-") === false) {
  210. $date .= "Z";
  211. }
  212. $date = preg_replace("/([0-9])T([0-9])/", "$1 $2", $date);
  213. $date = preg_replace("/([\+\-][0-9]{2}):([0-9]{2})/", "$1$2", $date);
  214. $date = strtotime($date);
  215. if ($date <= 0) {
  216. return ($defNow == true) ? gmdate("Y-m-d H:i:s", time()) : $this->zeroDate;
  217. }
  218. return gmdate("Y-m-d H:i:s", $date);
  219. }
  220. function getPostObject() {
  221. //it's defined at the end of this file
  222. $post = new bx_streams_blog_post();
  223. $post->title = $this->getElement("title", true);
  224. $post->content = $this->getElement("content", true);
  225. $post->content_extended = $this->getElement("content_extended", true);
  226. $post->summary = $this->getElement("summary", true);
  227. $post->status = $this->getElement("status");
  228. $post->comment_mode = $this->getElement("comment_mode");
  229. if (!$post->comment_mode) {
  230. $post->comment_mode = 99;
  231. }
  232. $post->uri = $this->getElement("uri");
  233. $post->tags = bx_metaindex::splitTags(trim($this->getElement("tags")));
  234. $post->trackbacks = $this->getElement("trackback");
  235. $post->autodiscovery = $this->getElement("autodiscovery");
  236. $post->status = $this->getElement("status");
  237. if (!$post->status) {
  238. $post->status = 1;
  239. }
  240. $post->date = $this->fixDate($this->getElement("created"));
  241. $post->expires = $this->fixDate($this->getElement("expires"), false);
  242. $post->lang = $this->getElement("lang", true);
  243. $post->post_info = "";
  244. return $post;
  245. }
  246. function insertEntry($id = null) {
  247. $parts = bx_collections::getCollectionAndFileParts($this->path, "output");
  248. $p = $parts['coll']->getFirstPluginMapByRequest("index", "html");
  249. $p = $p['plugin'];
  250. $colluri = $parts['coll']->uri;
  251. $blogid = $p->getParameter($colluri, "blogid");
  252. if ($blogid == null) {
  253. $blogid = 1;
  254. }
  255. $db = $GLOBALS['POOL']->db;
  256. $dbwrite = $GLOBALS['POOL']->dbwrite;
  257. $post = $this->getPostObject();
  258. if ($id) {
  259. //delete cache
  260. $GLOBALS['POOL']->cache->flush("plugins_blog_id_" . $id);
  261. $post->id = $id;
  262. } else {
  263. $post->id = $dbwrite->nextID($GLOBALS['POOL']->config->getTablePrefix() . "_sequences");
  264. }
  265. try {
  266. $post->author = bx_permm::getInstance()->getUsername();
  267. } catch (Exception $e) {
  268. $post->author = $this->getElement('author');
  269. if (!$post->author) {
  270. $post->author = "unknown";
  271. }
  272. }
  273. foreach (self::$adminPlugins as $plugin) {
  274. $post = call_user_func(array(
  275. "bx_plugins_blog_" . $plugin,
  276. "onInsertNewPost"
  277. ), $post);
  278. }
  279. $query = "insert into " . $this->tablePrefix . "blogposts
  280. (id, blog_id, post_author, post_date, post_expires, post_title, post_content, post_content_extended, post_uri, post_info, post_status, post_comment_mode, post_lang ";
  281. if ($blogEditOwnOnly == 1 && isset($_SESSION['_authsession']['data']['id'])) {
  282. $query .= ", post_author_id ";
  283. }
  284. $query .= ") values
  285. ($post->id,
  286. $blogid,
  287. " . $db->quote($post->author, 'text') . ",
  288. '" . $post->date . "',
  289. '" . $post->expires . "',
  290. " . $db->quote(bx_helpers_string::utf2entities($post->title), 'text') . ",
  291. " . $db->quote(bx_helpers_string::utf2entities($post->content), 'text') . ",
  292. " . $db->quote(bx_helpers_string::utf2entities($post->content_extended), 'text') . ",
  293. " . $db->quote($post->uri, 'text') . ",
  294. " . $db->quote(bx_helpers_string::utf2entities($post->getInfoString()), 'text') . ",
  295. " . $db->quote($post->status) . ",
  296. " . $db->quote($post->comment_mode) . ",
  297. " . $db->quote($post->lang) . " ";
  298. if ($blogEditOwnOnly == 1 && isset($_SESSION['_authsession']['data']['id'])) {
  299. $query .= "," . $db->quote($_SESSION['_authsession']['data']['id']);
  300. }
  301. $query .= ")";
  302. $res = $dbwrite->query($query);
  303. if (MDB2::isError($res)) {
  304. if ($res->code == -5) {
  305. //check if id really already exists or if we have another problem...
  306. $query = "select id from " . $this->tablePrefix . "blogposts where id = " . $post->id;
  307. $resid = $dbwrite->query($query);
  308. if ($resid->numRows() > 0) {
  309. //first set it to the max value of this table
  310. $resid = $dbwrite->query("select max(id) from blogposts");
  311. $maxid = $resid->fetchOne(0);
  312. if ($maxid > $post->id) {
  313. //this is maybe mysql only... I don't know, how sequences are stored in other DBs
  314. //shouldn't really matter as the while loop after it just takes longer otherwise
  315. $dbwrite->querywrite("update " . $this->tablePrefix . "_sequences_seq set sequence = $maxid");
  316. }
  317. //then loop through it, until we find an id, which fits
  318. while (MDB2::isError($res)) {
  319. //use global tableprefix for sequences for that
  320. $post->id = $GLOBALS['POOL']->dbwrite->nextID($GLOBALS['POOL']->config->getTablePrefix() . "_sequences");
  321. $query = "insert into " . $this->tablePrefix . "blogposts
  322. (id, blog_id, post_author, post_date, post_title, post_content, post_uri) values
  323. ($post->id, $blogid, '" . bx_permm::getInstance()->getUsername() . "', '" . $post->date . "', " . $db->quote($post->title) . "," . $db->quote($post->content) . "," . $db->quote($post->uri) . ")";
  324. $res = $dbwrite->query($query);
  325. }
  326. }
  327. else {
  328. throw new PopoonDBException($res);
  329. }
  330. } else {
  331. throw new PopoonDBException($res);
  332. }
  333. }
  334. $post->uri = bx_collections::sanitizeUrl(dirname($this->path)) . $post->uri . '.html';
  335. if ($post->id > 0) {
  336. bx_metaindex::setTags($post->uri, bx_metaindex::implodeTags($post->tags), true);
  337. bx_resourcemanager::setProperty($post->uri, "subject", bx_metaindex::implodeTags($post->tags), 'http://purl.org/dc/elements/1.1/');
  338. bx_resourcemanager::setProperty($post->uri, "title", $post->title, 'bx:');
  339. bx_resourcemanager::setProperty($post->uri, "content", $post->content, 'bx:');
  340. $this->updateCategories($post->id);
  341. if ($post->status == 1) {
  342. $this->weblogsPing();
  343. }
  344. if ($post->autodiscovery) {
  345. $this->getRemotePage($post->title, $post->content, $post->uri);
  346. }
  347. $this->sendTrackbacks($post->trackbacks, $post->title, $post->content, $post->uri);
  348. }
  349. }
  350. function weblogsPing() {
  351. if ($GLOBALS['POOL']->config->getConfProperty("noOutsideConnections") != "true") {
  352. /*$servicesExtended = array("http://rpc.pingomatic.com/","http://planet.freeflux.net/ping/");
  353. $servicesOld = array("http://rpc.technorati.com/rpc/ping");*/
  354. $services = bx_helpers_config::getProperty("blogWeblogsPing", true);
  355. if (!is_array($services)) {
  356. $services = array(
  357. $services
  358. );
  359. }
  360. if ($fixed = trim(bx_helpers_config::getProperty("blogWeblogsPingFixed", true))) {
  361. $services[] = $fixed;
  362. $services = array_unique($services);
  363. }
  364. $blogname = bx_helpers_config::getProperty("blogname");
  365. if (!$blogname) {
  366. $blogname = bx_helpers_config::getProperty("sitename");
  367. }
  368. $url = BX_WEBROOT . substr(bx_collections::getCollectionUri($this->path), 1);
  369. $noti = new lx_notifier();
  370. $checkurl = $url;
  371. $mainfeed = $url . "rss.xml";
  372. $topicurls = array(
  373. $url . 'atom.xml',
  374. $mainfeed
  375. );
  376. $noti->addWeblogUpdates(array(
  377. $mainfeed
  378. ), $services, $url, $blogname, $checkurl);
  379. /*
  380. $clouds = array('http://rpc.rsscloud.org:5337/rsscloud/ping');
  381. $noti->addRssClouds($topicurls,$clouds);
  382. */
  383. $hubs = array(
  384. "http://pubsubhubbub.appspot.com"
  385. );
  386. $noti->addPubSubHubs($topicurls, $hubs);
  387. $supid = self::getSUPId();
  388. $noti->addSup("http://friendfeed.com/api/public-sup-ping?supid=" . $supid . "&url=" . $mainfeed);
  389. $noti->notifyAll();
  390. }
  391. }
  392. function updateEntry($id) {
  393. $db = $GLOBALS['POOL']->dbwrite;
  394. $post = $this->getPostObject();
  395. $post->id = $id;
  396. //delete cache
  397. $GLOBALS['POOL']->cache->flush("plugins_blog_id_" . $id);
  398. $row = $db->queryRow("select post_info, post_status from " . $this->tablePrefix . "blogposts where id = $id", null, MDB2_FETCHMODE_ASSOC);
  399. if (!is_array($row)) {
  400. $this->insertEntry($id);
  401. }
  402. if ($row['post_info']) {
  403. $post->info = new domdocument();
  404. $post->info->loadXML('<info>' . $row['post_info'] . '</info>');
  405. }
  406. $post->status_old = $row['post_status'];
  407. foreach (self::$adminPlugins as $plugin) {
  408. $func = array(
  409. "bx_plugins_blog_" . $plugin,
  410. "onUpdatePost"
  411. );
  412. if (is_callable($func)) {
  413. $post = call_user_func($func, $post);
  414. }
  415. }
  416. if ($post->title == '') {
  417. $post->title = "No Title";
  418. }
  419. $query = "update " . $this->tablePrefix . "blogposts set post_title = " . $db->quote(bx_helpers_string::utf2entities($post->title)) . "," . "post_content = " . $db->quote(bx_helpers_string::utf2entities($post->content)) . "," . "post_content_extended = " . $db->quote(bx_helpers_string::utf2entities($post->content_extended)) . "," . "post_content_summary = " . $db->quote(bx_helpers_string::utf2entities($post->summary)) . "," . "post_status = " . $db->quote($post->status) . "," . "post_expires = " . $db->quote($post->expires) . "," . "post_comment_mode = " . $db->quote($post->comment_mode);
  420. if ($post->lang) {
  421. $query .= ", post_lang = " . $db->quote($post->lang);
  422. }
  423. if ($post->date) {
  424. $query .= ", post_date = " . $db->quote($post->date);
  425. }
  426. if ($post->uri) {
  427. $query .= ", post_uri = " . $db->quote($post->uri);
  428. } else {
  429. $post->uri = self::getUriById($post->id);
  430. }
  431. if ($post->info instanceof DomDocument) {
  432. $query .= ", post_info = " . $db->quote(bx_helpers_string::utf2entities($post->getInfoString()), 'text');
  433. }
  434. $query .= " where id = '" . $post->id . "'";
  435. $res = $db->query($query);
  436. $post->uri = bx_collections::sanitizeUrl(dirname($this->path)) . $post->uri . '.html';
  437. if ($post->id > 0) {
  438. if ($post->autodiscovery) {
  439. $this->getRemotePage($post->title, $post->content, $post->uri);
  440. }
  441. $this->sendTrackbacks($post->trackbacks, $post->title, $post->content, $post->uri);
  442. bx_metaindex::setTags($post->uri, bx_metaindex::implodeTags($post->tags), true);
  443. bx_resourcemanager::setProperty($post->uri, "subject", bx_metaindex::implodeTags($post->tags), 'http://purl.org/dc/elements/1.1/');
  444. //update categories
  445. bx_resourcemanager::setProperty($post->uri, "title", $post->title, 'bx:');
  446. bx_resourcemanager::setProperty($post->uri, "content", $post->content, 'bx:');
  447. $this->updateCategories($post->id);
  448. if ($post->status == 1) { // && $post->status_old != 1) {
  449. $this->weblogsPing();
  450. }
  451. }
  452. }
  453. function updateCategories($id) {
  454. $this->xp->registerNamespace("sa-cat", "http://sixapart.com/atom/category#");
  455. $res = $this->xp->query("/atom:entry/sa-cat:categories");
  456. if ($res->length > 0) {
  457. $res = $this->xp->query("/atom:entry/sa-cat:categories/dc:subject");
  458. //get category ids
  459. $cats = array();
  460. foreach ($res as $cat) {
  461. $cats[] = $cat->nodeValue;
  462. }
  463. self::updateCategoriesDirect($id, $cats, false, $this->tablePrefix);
  464. }
  465. }
  466. static function deleteEntryDirect($id, $path) {
  467. $tablePrefix = self::getTablePrefix($path);
  468. $query = "select post_uri, blog_id from " . $tablePrefix . "blogposts where id = '$id'";
  469. $res = $GLOBALS['POOL']->db->query($query);
  470. $row = $res->fetchRow(MDB2_FETCHMODE_ASSOC);
  471. $postPath = bx_helpers_string::removeDoubleSlashes($path . $row['post_uri'] . '.html');
  472. $query = "delete from " . $tablePrefix . "properties where path = '$postPath'";
  473. $GLOBALS['POOL']->dbwrite->query("$query");
  474. $query = "delete from " . $tablePrefix . "properties2tags where path = '$postPath'";
  475. $GLOBALS['POOL']->dbwrite->query("$query");
  476. $query = "delete from " . $tablePrefix . "blogposts where id = '$id' and blog_id = '" . $row['blog_id'] . "'";
  477. $GLOBALS['POOL']->dbwrite->query("$query");
  478. $query = "delete from " . $tablePrefix . "blogposts2categories where blogposts_id = '$id'";
  479. $GLOBALS['POOL']->dbwrite->query("$query");
  480. $query = "delete from " . $tablePrefix . "blogcomments where comment_posts_id = '$id'";
  481. $GLOBALS['POOL']->dbwrite->query("$query");
  482. return true;
  483. }
  484. static function updateCategoriesDirect($id, $cats, $isId = false, $tablePrefix = null) {
  485. /*if (!$tablePrefix) {
  486. $tablePrefix = self::getTablePrefix($this->path);
  487. }*/
  488. if (!$isId) {
  489. if (count($cats) == 0) {
  490. $ids = array();
  491. } else {
  492. // if ($cat[0] == "__default") {
  493. // search for default cat
  494. // } else {
  495. //search in fullname
  496. $query = "select id from " . $tablePrefix . "blogcategories where fullname in ('" . bx_helpers_string::utf2entities(implode("','", $cats)) . "')";
  497. $res = $GLOBALS['POOL']->db->query($query);
  498. $ids = $res->fetchCol();
  499. // if no ids found, try with uri
  500. if (count($ids) == 0) {
  501. $query = "select id from " . $tablePrefix . "blogcategories where uri in ('" . bx_helpers_string::utf2entities(strtolower(implode("','", $cats))) . "')";
  502. $res = $GLOBALS['POOL']->db->query($query);
  503. $ids = $res->fetchCol();
  504. }
  505. // if no ids found, try with enforced utf2entities
  506. if (count($ids) != count($cats)) {
  507. $query = "select id from " . $tablePrefix . "blogcategories where fullname in ('" . bx_helpers_string::utf2entities(implode("','", $cats), true) . "')";
  508. $res = $GLOBALS['POOL']->db->query($query);
  509. $ids = $res->fetchCol();
  510. }
  511. // } // end else
  512. // if still not found, and its $cats[0] contains "moblog"... or __default
  513. if (count($ids) == 0 && ($cats[0] == '__default' || strpos(strtolower($cats[0]), "moblog") !== false)) {
  514. //search for a cat containing moblog as well in title or category
  515. $query = "select id from " . $tablePrefix . "blogcategories where fullname like '%moblog%' or uri like '%moblog%' LIMIT 1";
  516. $res = $GLOBALS['POOL']->db->query($query);
  517. $ids = $res->fetchCol();
  518. }
  519. // if still not found, just take the default one
  520. if (count($ids) == 0) {
  521. // take the default one, if there is one
  522. //TODO
  523. // otherwise the first one
  524. $query = "select id from " . $tablePrefix . "blogcategories where uri != 'root' order by l LIMIT 1";
  525. $res = $GLOBALS['POOL']->db->query($query);
  526. $ids = $res->fetchCol();
  527. }
  528. }
  529. } else {
  530. $ids = $cats;
  531. }
  532. //delete not choosen ids
  533. if (count($ids) > 0) {
  534. $query = "delete from " . $tablePrefix . "blogposts2categories where blogposts_id = $id and not( blogcategories_id in (" . implode(",", $ids) . "))";
  535. $res = $GLOBALS['POOL']->dbwrite->query($query);
  536. //get old categories
  537. $query = "select blogcategories_id from " . $tablePrefix . "blogposts2categories where blogposts_id = $id and ( blogcategories_id in (" . implode(",", $ids) . "))";
  538. $res = $GLOBALS['POOL']->dbwrite->query($query);
  539. $oldids = $res->fetchCol();
  540. } else {
  541. $query = "delete from " . $tablePrefix . "blogposts2categories where blogposts_id = $id ";
  542. $res = $GLOBALS['POOL']->dbwrite->query($query);
  543. $oldids = array();
  544. }
  545. // add new categories
  546. foreach ($ids as $value) {
  547. if (!(in_array($value, $oldids))) {
  548. $seqid = $GLOBALS['POOL']->dbwrite->nextID($GLOBALS['POOL']->config->getTablePrefix() . "_sequences");
  549. $query = "insert into " . $tablePrefix . "blogposts2categories (id, blogposts_id, blogcategories_id) VALUES ($seqid, $id, $value)";
  550. $res = $GLOBALS['POOL']->dbwrite->query($query);
  551. }
  552. }
  553. }
  554. function getElement($element, $clean = false) {
  555. $res = $this->xp->query("/atom:entry/atom:$element/*|/atom:entry/atom:$element/text()");
  556. $xml = "";
  557. foreach ($res as $node) {
  558. if ($node->nodeType == 1 && $node->getAttribute("keep") == "true") {
  559. return false;
  560. }
  561. $xml .= $this->dom->saveXML($node);
  562. }
  563. if ($clean && $GLOBALS['POOL']->config->blogXssCleanPosts == 'true') {
  564. // clean up comment
  565. if (class_exists('tidy')) {
  566. $tidy = new tidy();
  567. if (!$tidy) {
  568. throw new Exception("Something went wrong with tidy initialisation. Maybe you didn't enable ext/tidy in your PHP installation. Either install it or remove the tidy transformer from your sitemap.xml");
  569. }
  570. } else {
  571. $tidy = false;
  572. }
  573. if ($tidy) {
  574. $tidy->parseString($xml, $this->tidyOptions, "utf8");
  575. $tidy->cleanRepair();
  576. $xml = popoon_classes_externalinput::basicClean((string) $tidy);
  577. // and tidy it again
  578. $tidy->parseString($xml);
  579. $tidy->cleanRepair();
  580. $xml = (string) $tidy;
  581. }
  582. }
  583. return $xml;
  584. }
  585. function returnCategories() {
  586. $parts = bx_collections::getCollectionAndFileParts($this->path, "output");
  587. $p = $parts['coll']->getFirstPluginMapByRequest("index", "html");
  588. $p = $p['plugin'];
  589. $colluri = $parts['coll']->uri;
  590. $blogid = $p->getParameter($colluri, "blogid");
  591. if (!$blogid) {
  592. $blogid = 1;
  593. }
  594. $res = $GLOBALS['POOL']->db->query("select id, fullname from " . $this->tablePrefix . "blogcategories where status = 1 and " . $this->tablePrefix . "blogcategories.blog_id = $blogid order by fullname ");
  595. $xml = '<categories xmlns="http://sixapart.com/atom/category#" xmlns:dc="http://purl.org/dc/elements/1.1/">';
  596. while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) {
  597. $xml .= '<dc:subject xml:id="cat' . $row['id'] . '">' . htmlspecialchars(html_entity_decode($row['fullname'], ENT_NOQUOTES, "UTF-8")) . '</dc:subject>';
  598. }
  599. $xml .= '</categories>';
  600. return $xml;
  601. }
  602. function contentOnWrite($content) {
  603. }
  604. static function getIdByUri($uri, $path) {
  605. $tablePrefix = self::getTablePrefix($path);
  606. $res = $GLOBALS['POOL']->db->query("select id from " . $tablePrefix . "blogposts where post_uri = '" . $uri . "'");
  607. return $res->fetchOne(0);
  608. }
  609. static function getUriById($id) {
  610. $tablePrefix = $GLOBALS['POOL']->config->getTablePrefix();
  611. $res = $GLOBALS['POOL']->db->query("select post_uri from " . $tablePrefix . "blogposts where id = '" . $id . "'");
  612. return $res->fetchOne(0);
  613. }
  614. static function getUniqueUri($uri, $path) {
  615. $tablePrefix = self::getTablePrefix($path);
  616. //check if uri already exists
  617. if (trim($uri) == '') {
  618. $uri = 'none';
  619. }
  620. $query = "select id from " . $tablePrefix . "blogposts where post_uri = '$uri'";
  621. $resid = $GLOBALS['POOL']->db->query($query);
  622. $newuri = $uri;
  623. $z = 1;
  624. while ($resid->numRows() > 0) {
  625. $z++;
  626. $newuri = $uri . "-" . $z;
  627. $query = "select id from " . $tablePrefix . "blogposts where post_uri = '$newuri'";
  628. $resid = $GLOBALS['POOL']->db->query($query);
  629. }
  630. $uri = $newuri;
  631. return $uri;
  632. }
  633. static function getTablePrefix($path) {
  634. if (!isset($tablePrefixes['$path'])) {
  635. $parts = bx_collections::getCollectionAndFileParts($path, "output");
  636. $p = $parts['coll']->getFirstPluginMapByRequest("index", "html");
  637. $p = $p['plugin'];
  638. $tablePrefixes['$path'] = $GLOBALS['POOL']->config->getTablePrefix() . $p->getParameter($parts['coll']->uri, "tableprefix");
  639. }
  640. return $tablePrefixes['$path'];
  641. }
  642. public function sendTrackbacks($trackbacks, $title, $content, $uri) {
  643. if ($trackbacks) {
  644. foreach (split(" ", $trackbacks) as $trackback) {
  645. $req = new HTTP_Request($trackback);
  646. $req->setMethod(HTTP_REQUEST_METHOD_POST);
  647. $req->addPostData("title", html_entity_decode(strip_tags($title), ENT_COMPAT, 'UTF-8'));
  648. $req->addPostData("excerpt", substr(html_entity_decode(strip_tags($content), ENT_COMPAT, 'UTF-8'), 0, 200) . " ...");
  649. $uri = substr($uri, strrpos($uri, "/"));
  650. $uri = str_replace("/", "", $uri);
  651. $uri = BX_WEBROOT_W . dirname($this->path) . '/archive/' . $uri;
  652. $req->addPostData("url", $uri);
  653. if ($GLOBALS['POOL']->config->blogname) {
  654. $blogname = $GLOBALS['POOL']->config->blogname;
  655. $req->addPostData("blog_name", $blogname);
  656. } else {
  657. $blogname = $GLOBALS['POOL']->config->sitename;
  658. $req->addPostData("blog_name", $blogname);
  659. }
  660. if (PEAR::isError($req->sendRequest())) {
  661. error_log("Trackback to $trackback didn't work.");
  662. }
  663. }
  664. }
  665. }
  666. public function getRemotePage($title, $content, $uri) {
  667. $dom = new DomDocument();
  668. $dom->loadHTML($content);
  669. $domxpath = new DomXPath($dom);
  670. $results = $domxpath->query("//a");
  671. foreach ($results as $result) {
  672. $href = $result->getAttribute("href");
  673. $sc = popoon_helpers_simplecache::getInstance();
  674. $page = $sc->simpleCacheHttpRead($href, 1);
  675. if (preg_match('#trackback:ping="([^"]+)"#', $page, $matches)) {
  676. $this->sendTrackbacks($matches[1], $title, $content, $uri);
  677. }
  678. }
  679. }
  680. static function getSUPid() {
  681. return "flx-" . substr(md5(str_replace("http://www.", "http://", BX_WEBROOT)), 0, 10);
  682. }
  683. // maybe put this into a helper
  684. }
  685. class bx_streams_blog_post {
  686. public $title = null;
  687. public $content = null;
  688. /*public $content_extended = null;
  689. public $summary = null;*/
  690. public $uri = null;
  691. public $tags = null;
  692. public $trackbacks = null;
  693. public $autodiscovery = null;
  694. public $status = null;
  695. public $date = null;
  696. public $id = null;
  697. public $info = null;
  698. public function getInfo() {
  699. if (!$this->info) {
  700. $this->info = new domdocument();
  701. $this->info->appendChild($this->info->createElement("info"));
  702. }
  703. return $this->info;
  704. }
  705. public function appendInfoString($infoString) {
  706. if ($infoString) {
  707. $info = $this->getInfo();
  708. $dom = new domdocument();
  709. $dom->loadXML($infoString);
  710. $info->documentElement->appendChild($info->importNode($dom->documentElement, true));
  711. }
  712. }
  713. public function getInfoString() {
  714. if (!$this->info) {
  715. return "";
  716. }
  717. if (!$this->info->documentElement->hasChildNodes()) {
  718. return "";
  719. }
  720. $xml = "";
  721. foreach ($this->info->documentElement->childNodes as $child) {
  722. $xml .= $this->info->saveXML($child);
  723. }
  724. return $xml;
  725. }
  726. }