content.module

  1. 6.x modules/content/content.module
  2. 4.x modules/content/content.module
  3. 5.x modules/content/content.module

File

modules/content/content.module
View source
  1. <?php
  2. /**
  3. * This module lets administrators create content, when then appear can appear in a block.
  4. */
  5. function content_menu() {
  6. $items = array();
  7. $items["admin/config/content"] = array(
  8. "title" => "Content",
  9. "description" => "Manage content in " . variable_get("system_name", "FlightPath") . ". Ex: Announcements, Pages, etc.",
  10. "page_callback" => "content_display_content_admin_list",
  11. "access_arguments" => array("admin_content"),
  12. "page_settings" => array(
  13. "page_has_search" => FALSE,
  14. "menu_icon" => fp_get_module_path('content') . "/icons/application_edit.png",
  15. "page_show_title" => TRUE,
  16. "page_banner_is_link" => TRUE,
  17. "page_hide_report_error" => TRUE,
  18. "menu_links" => array(
  19. 0 => array(
  20. "text" => "Admin Console",
  21. "path" => "admin-tools/admin",
  22. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  23. ),
  24. ),
  25. ),
  26. "type" => MENU_TYPE_TAB,
  27. "tab_family" => "content_list",
  28. );
  29. $items["content/delete"] = array(
  30. "page_callback" => "content_handle_delete_content",
  31. "access_arguments" => array("admin_content"),
  32. "type" => MENU_TYPE_CALLBACK,
  33. );
  34. /* // We will create a new menu item for editing each content type
  35. // currently known to the system.
  36. $types = content_get_types();
  37. foreach ($types as $type => $details) {
  38. // content/add/TYPE
  39. $items["content/add/$type"] = array(
  40. "page_callback" => "fp_render_form",
  41. "page_arguments" => array("content_edit_content_form", "", $type, "new"),
  42. "access_arguments" => array("edit_$type" . "_content"),
  43. "page_settings" => array(
  44. "page_has_search" => FALSE,
  45. "page_banner_is_link" => TRUE,
  46. "page_hide_report_error" => TRUE,
  47. "menu_links" => array(
  48. 0 => array(
  49. "text" => "Admin Console",
  50. "path" => "admin-tools/admin",
  51. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  52. ),
  53. 1 => array(
  54. "text" => "Back to content list",
  55. "path" => "admin/config/content",
  56. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  57. ),
  58. ),
  59. ),
  60. "type" => MENU_TYPE_TAB,
  61. "tab_parent" => "admin/config/content",
  62. );
  63. }
  64. */
  65. // content/add/TYPE
  66. $items["content/add/%"] = array(
  67. "page_callback" => "fp_render_form",
  68. "page_arguments" => array("content_edit_content_form", "", 2, "new"),
  69. "access_callback" => "content_user_access",
  70. "access_arguments" => array("add_type", 2),
  71. "page_settings" => array(
  72. "page_has_search" => FALSE,
  73. "page_banner_is_link" => TRUE,
  74. "page_hide_report_error" => TRUE,
  75. "menu_links" => array(
  76. 0 => array(
  77. "text" => "Admin Console",
  78. "path" => "admin-tools/admin",
  79. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  80. ),
  81. 1 => array(
  82. "text" => "Back to content list",
  83. "path" => "admin/config/content",
  84. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  85. ),
  86. ),
  87. ),
  88. "type" => MENU_TYPE_TAB,
  89. "tab_parent" => "admin/config/content",
  90. );
  91. // content/CID/edit
  92. $items["content/%/edit"] = array(
  93. "page_callback" => "fp_render_form",
  94. "page_arguments" => array("content_edit_content_form", "", "", 1),
  95. "access_callback" => "content_user_access",
  96. "access_arguments" => array("edit_cid", 1),
  97. "page_settings" => array(
  98. "page_has_search" => FALSE,
  99. "page_banner_is_link" => TRUE,
  100. "page_hide_report_error" => TRUE,
  101. "menu_links" => array(
  102. 0 => array(
  103. "text" => "Admin Console",
  104. "path" => "admin-tools/admin",
  105. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  106. ),
  107. 1 => array(
  108. "text" => "Back to content list",
  109. "path" => "admin/config/content",
  110. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  111. ),
  112. ),
  113. ),
  114. "type" => MENU_TYPE_TAB,
  115. "tab_parent" => "admin/config/content",
  116. );
  117. $items["content/%"] = array(
  118. "page_callback" => "content_view_content",
  119. "page_arguments" => array(1),
  120. "access_callback" => "content_user_access",
  121. "access_arguments" => array("view_cid", 1),
  122. "page_settings" => array(
  123. "page_has_search" => FALSE,
  124. "page_show_title" => TRUE,
  125. "page_banner_is_link" => TRUE,
  126. "page_hide_report_error" => TRUE,
  127. "menu_links" => array(
  128. 0 => array(
  129. "text" => "Edit this content",
  130. "path" => "content/%CONTENT_CID%/edit",
  131. "query" => "",
  132. ),
  133. ),
  134. ),
  135. "type" => MENU_TYPE_TAB,
  136. "tab_parent" => "admin/config/content",
  137. );
  138. return $items;
  139. }
  140. /**
  141. * Custom user access function to determine if the user can add, edit, etc, the content
  142. *
  143. *
  144. * @param unknown_type $op
  145. * @param unknown_type $var
  146. */
  147. function content_user_access($op, $var) {
  148. // for now, just return TRUE
  149. //fpm("checking access to $op on $var");
  150. return TRUE;
  151. }
  152. /**
  153. * This is an implementation of hook_menu_handle_replacement_pattern.
  154. * It will search for and replace replacement patterns which we are aware of it in $str.
  155. */
  156. function content_menu_handle_replacement_pattern($str) {
  157. $cid = @$_REQUEST["cid"];
  158. if ($cid) {
  159. $content = content_load($cid);
  160. if (is_array($content)) {
  161. if (strpos($str, "%CONTENT_CID%") !== 0) {
  162. // It contains this replacement pattern!
  163. $str = str_replace("%CONTENT_CID%", $cid, $str);
  164. }
  165. if (strpos($str, "%CONTENT_TYPE%") !== 0) {
  166. // It contains this replacement pattern!
  167. $str = str_replace("%CONTENT_TYPE%", $content["type"], $str);
  168. }
  169. }
  170. }
  171. return $str;
  172. }
  173. /**
  174. * Display the content specified in the GET's cid.
  175. *
  176. */
  177. function content_view_content() {
  178. $rtn = "";
  179. $content = content_load($_GET["cid"]);
  180. $types = content_get_types();
  181. $author = fp_load_user($content["user_id"]);
  182. if (!strstr($content["title"], "[hide]")) {
  183. fp_set_title($content["title"]);
  184. }
  185. fp_add_body_class("content-type-" . $content["type"]);
  186. $rtn .= "<div class='content-view content-view-{$content["type"]}'>";
  187. $rtn .= "<div class='content-submitted'>" . t("Submitted by") . " " . $author->name . " " . t("on");
  188. $rtn .= " " . format_date($content["posted"]) . "</div>";
  189. $rtn .= "<div class='content-body'>" . $content["body"] . "</div>";
  190. $rtn .= "</div>";
  191. return $rtn;
  192. }
  193. /**
  194. * This form lets the user edit some piece of content
  195. *
  196. */
  197. function content_edit_content_form($type = "", $cid = "") {
  198. $form = array();
  199. $m = 0;
  200. fp_add_css(fp_get_module_path("content") . "/css/content.css");
  201. if ($type == "") {
  202. @$type = $_REQUEST["type"];
  203. }
  204. if ($cid == "") {
  205. @$cid = $_REQUEST["cid"];
  206. }
  207. $types = content_get_types();
  208. if ($cid != "new") {
  209. $content = content_load($cid);
  210. fp_set_title(t("Editing") . " " . $content["title"] . "");
  211. // Re-set $type, just in case the user put the wrong type in the
  212. // URL
  213. $type = $content["type"];
  214. }
  215. else {
  216. // New piece of content
  217. $content = array();
  218. fp_set_title(t("Add new") . " " . $types[$type]["title"]);
  219. }
  220. // Does the user have permission to edit this content?
  221. if (!user_has_permission("edit_$type" . "_content")) {
  222. fp_add_message(t("Sorry, you do not have permission to edit that content type."));
  223. fp_goto("admin/config/content");
  224. return;
  225. }
  226. $form["type"] = array(
  227. "type" => "hidden",
  228. "value" => $type,
  229. );
  230. $form["cid"] = array(
  231. "type" => "hidden",
  232. "value" => $cid,
  233. );
  234. $form["title"] = array(
  235. "type" => "textfield",
  236. "label" => t("Title:"),
  237. "value" => $content["title"],
  238. "required" => TRUE,
  239. "description" => t("To hide the title, you may start
  240. it with [hide]. For example: \"[hide] this is a sample.\""),
  241. );
  242. $form["body"] = array(
  243. "type" => "textarea",
  244. "label" => t("Body:"),
  245. "rows" => 15,
  246. "value" => $content["body"],
  247. );
  248. // Are there any settings we should show?
  249. if (is_array($types[$type]["settings"])) {
  250. foreach($types[$type]["settings"] as $field_name => $field_details) {
  251. $form[$field_name] = $field_details;
  252. // Add in default value previously saved, if available.
  253. $form[$field_name]["value"] = $content["settings"][$field_name];
  254. }
  255. }
  256. // Draw the controls (buttons)
  257. $form["mark" . $m++] = array(
  258. "value" => "<div class='content-edit-controls'>",
  259. );
  260. $form["submit_submit"] = array(
  261. "type" => "submit",
  262. "value" => t("Submit"),
  263. );
  264. $form["submit_delete"] = array(
  265. "type" => "submit",
  266. "value" => t("Delete"),
  267. "confirm" => t('Are you sure you wish to delete this?\nThis action cannot be undone.'),
  268. );
  269. $form["mark" . $m++] = array(
  270. "value" => "</div>",
  271. );
  272. return $form;
  273. }
  274. /**
  275. * Submit handler for the edit content form.
  276. *
  277. * @param unknown_type $form
  278. * @param unknown_type $form_state
  279. */
  280. function content_edit_content_form_submit(&$form, $form_state) {
  281. global $user;
  282. $values = $form_state["values"];
  283. $now = time();
  284. $types = content_get_types();
  285. $type = $values["type"];
  286. // Does the user have permission to edit this content?
  287. if (!user_has_permission("edit_$type" . "_content")) {
  288. fp_add_message(t("Sorry, you do not have permission to edit that content type."));
  289. fp_goto("admin/config/content");
  290. return;
  291. }
  292. // Assemble our "settings" array, if available.
  293. $settings = array();
  294. if (is_array($types[$type]["settings"])) {
  295. foreach($types[$type]["settings"] as $field_name => $field_details) {
  296. $settings[$field_name] = $values[$field_name];
  297. }
  298. }
  299. if ($values["submit_submit"] != "") {
  300. // a submission (not a deletion) is taking place
  301. // if the cid == "new" then we should do an insert. Otherwise,
  302. // we should do an update.
  303. if ($values["cid"] == "new") {
  304. db_query("INSERT INTO content (user_id, type, title, body, settings, posted, updated)
  305. VALUES ('?', '?', '?', '?', '?', '?', '?')
  306. ", $user->id, $values["type"], $values["title"], $values["body"], serialize($settings), $now, $now);
  307. $new_id = db_insert_id();
  308. $form["#redirect"] = array(
  309. "path" => "content/$new_id/edit",
  310. );
  311. }
  312. else {
  313. // We are editing an existing piece of content-- just update.
  314. db_query("UPDATE content
  315. SET title = '?',
  316. body = '?',
  317. settings = '?',
  318. updated = '?'
  319. WHERE cid = '?'
  320. ", $values["title"], $values["body"], serialize($settings), $now, $values["cid"]);
  321. }
  322. fp_add_message(t("%title has been saved successfully.", array("%title" => $values["title"])));
  323. }
  324. // Should be we deleting things?
  325. if ($values["submit_delete"] != "") {
  326. db_query("DELETE FROM content WHERE cid = '?' ", $values["cid"]);
  327. fp_add_message(t("%title has been deleted successfully.", array("%title" => $values["title"])));
  328. $form["#redirect"] = array(
  329. "path" => "admin/config/content",
  330. );
  331. }
  332. }
  333. /**
  334. * Load the content from the database and return an array, by calling hook_content_load.
  335. *
  336. * @param unknown_type $cid
  337. */
  338. function content_load($cid) {
  339. $rtn = array();
  340. $rtn["cid"] = $cid;
  341. $modules = modules_implement_hook("content_load");
  342. foreach ($modules as $module) {
  343. // Since PHP 5.4 removes call-time pass by reference,
  344. // I cannot use call_user_func. Instead, I will call the
  345. // functions directly like so:
  346. // $name($val).
  347. $function = $module . "_content_load";
  348. $function($rtn);
  349. }
  350. return $rtn;
  351. }
  352. /**
  353. * Implementation of content's hook_content_load
  354. *
  355. * We simply wish to load from our db table. The cid is in
  356. * $content["cid"].
  357. *
  358. * @param unknown_type $content
  359. */
  360. function content_content_load(&$content) {
  361. $res = db_query("SELECT * FROM content WHERE cid = '?' ", $content["cid"]);
  362. $cur = db_fetch_array($res);
  363. if ($cur["settings"] != "") {
  364. $arr = unserialize($cur["settings"]);
  365. $cur["settings"] = $arr;
  366. }
  367. if ($cur && is_array($cur) && count($cur) > 0) {
  368. $content += $cur;
  369. }
  370. }
  371. /**
  372. * Sample hook for hook_content_load
  373. *
  374. * This hook lets modules act on content as it is being loaded. Notice
  375. * the content is being passed by reference, so whatever changes you make
  376. * to this array will be added in. Nothing needs to be returned.
  377. *
  378. * @param unknown_type $content
  379. */
  380. function hook_content_load(&$content) {
  381. $content["new_field"] = "something something";
  382. }
  383. function content_handle_delete_content() {
  384. $aid = $_REQUEST["aid"];
  385. db_query("UPDATE content SET delete_flag = '1'
  386. WHERE aid = '?' ", $aid);
  387. fp_add_message(t("Content successfully deleted."));
  388. fp_goto("admin/config/content");
  389. }
  390. /**
  391. * Display a list of content for the administrator
  392. */
  393. function content_display_content_admin_list() {
  394. $rtn = "";
  395. //fp_add_css(fp_get_module_path("content") . "/css/content.css");
  396. $rtn .= "<br><b>" .t("Create new content:") . "</b>
  397. <table border='1' width='100%' cellpadding='4'>";
  398. // Go through all available content types and provide a link.
  399. $types = content_get_types();
  400. // We expect types to be returned like this:
  401. // ["page"]["title"] = "Basic Page";
  402. // ["page"]["description"] = "This is a standard page.";
  403. foreach ($types as $type => $details) {
  404. if (user_has_permission("edit_$type" . "_content")) {
  405. $rtn .= "<tr>
  406. <td>" . l($details["title"], "content/add/$type") . "</td>
  407. <td>" . $details["description"] . "</td></tr>";
  408. }
  409. }
  410. $rtn .= "</table>
  411. <hr>";
  412. // Show a table of current content in the system.
  413. $rtn .= "<b>" . t("Existing content:") . "</b>";
  414. @$filter = $_GET["filter"];
  415. $rtn .= "<form action='" . fp_url("admin/config/content") . "' method='GET'>
  416. " . t("Display type:") . " &nbsp; <select name='filter'>
  417. <option value=''>" . t(" -- Any --") . "</option>";
  418. foreach ($types as $type => $details) {
  419. $sel = ($type == $filter) ? "selected" : "";
  420. $rtn .= "<option value='$type' $sel>" . $details["title"] . "</option>";
  421. }
  422. $rtn .= "</select><input type='submit' value='-&gt;'> </form>";
  423. $rtn .= "<table width='100%' border='1' class='tenpt'>
  424. <tr>
  425. <th>" . t("Title") . "</th>
  426. <th>" . t("Edit") . "</th>
  427. <th>" . t("Type") . "</th>
  428. <th>" . t("Author") . "</th>
  429. <th>" . t("Updated") . "</th>
  430. </tr>";
  431. if ($filter != "") {
  432. $res = db_query("SELECT * FROM content WHERE type = '?' ORDER BY title", $filter);
  433. }
  434. else {
  435. $res = db_query("SELECT * FROM content ORDER BY title");
  436. }
  437. while ($cur = db_fetch_array($res)) {
  438. $author = fp_load_user($cur["user_id"]);
  439. $author_name = "";
  440. if ($author && isset($author->name)) {
  441. $author_name = $author->name;
  442. }
  443. $updated = format_date($cur["updated"]);
  444. //$rtn .= "<tr><td valign='top'>" . l($cur["title"], "content/{$cur["cid"]}") . "</td>";
  445. $rtn .= "<tr><td valign='top'>" . $cur["title"] . "</td>";
  446. if (user_has_permission("edit_{$cur["type"]}" . "_content")) {
  447. $rtn .= "
  448. <td valign='top'>" . l(t("edit"), "content/{$cur["cid"]}/edit") . "</td>";
  449. }
  450. else {
  451. $rtn .= "<td>&nbsp;</td>";
  452. }
  453. $rtn .= "
  454. <td valign='top'>" . $cur["type"] . "</td>
  455. <td valign='top'>" . $author_name . "</td>
  456. <td valign='top'>" . $updated . "</td>
  457. </tr>";
  458. }
  459. $rtn .= "</table>";
  460. return $rtn;
  461. }
  462. /**
  463. * Return an array with all the possible content types known to FlightPath
  464. *
  465. * Modules may declare their content types using the hook_content_register_content_type hook.
  466. * You should clear the cache after creating a new content type.
  467. *
  468. */
  469. function content_get_types() {
  470. $rtn = array();
  471. $modules = modules_implement_hook("content_register_content_type");
  472. foreach($modules as $module) {
  473. $types = call_user_func($module . '_content_register_content_type');
  474. $rtn += $types;
  475. }
  476. return $rtn;
  477. }
  478. /**
  479. * Implementation of this module's hook_content_register_content_type.
  480. *
  481. * I mainly just want to register the "page" content type, for a basic
  482. * web page set up.
  483. *
  484. */
  485. function content_content_register_content_type() {
  486. return array(
  487. "page" => array(
  488. "title" => t("Page"),
  489. "description" => t("This is a basic web page."),
  490. ),
  491. );
  492. }
  493. /**
  494. * Sample hook other modules implement to register a content type.
  495. *
  496. * Simply return an array as illustrated below to register your
  497. * module's content types.
  498. *
  499. * IMPORTNAT: The type's machine name must be a valid variable name.
  500. * No spaces or strange symbols.
  501. *
  502. */
  503. function hook_content_register_content_type() {
  504. $arr = array(
  505. "type_1" => array(
  506. "title" => t("Type One"),
  507. "description" => t("This is a content type."),
  508. "settings" => array(),
  509. ),
  510. "type_2" => array(
  511. "title" => t("Type Two"),
  512. "description" => t("This is another content type."),
  513. "settings" => array(),
  514. ),
  515. );
  516. return $arr;
  517. }
  518. /**
  519. * Return the HTML rendering the content we have in the database.
  520. */
  521. function content_render_content($bool_show_delete = FALSE) {
  522. $rtn = "";
  523. $res = db_query("SELECT * FROM content WHERE delete_flag = 0
  524. ORDER BY posted DESC");
  525. while ($cur = db_fetch_array($res)) {
  526. $rtn .= "<div class='content'>
  527. <div class='content-text'>" . filter_markup($cur["content"], "full") . "</div>
  528. <div class='content-posted'>" . t("Posted") . " " . date("D, M jS Y - g:ia", $cur["posted"]) . "</div>";
  529. if ($bool_show_delete) {
  530. $delete_link = "";
  531. $delete_link = fp_get_js_confirm_link(t("Are you sure you wish to delete this content?"), 'window.location="' . fp_url("content/delete", "aid=" . $cur["aid"]) . '"', t("Delete?"));
  532. $rtn .= "<div class='content-delete'>$delete_link</div>";
  533. }
  534. $rtn .= "</div>";
  535. }
  536. return $rtn;
  537. }
  538. /**
  539. * Implementation of hook_perm
  540. *
  541. * We want to create a permission for every content type.
  542. *
  543. */
  544. function content_perm() {
  545. $rtn = array();
  546. $rtn["admin_content"] = array(
  547. "title" => t("Administer Content"),
  548. "description" => t("The user needs this permission to access the content page at all, in
  549. addition to specific permissions listed below for editing
  550. different content types."),
  551. );
  552. $types = content_get_types();
  553. foreach ($types as $type => $details) {
  554. $rtn ["edit_$type" . "_content"] = array(
  555. "title" => t("Edit") . " " . $details["title"] . " " . t("content"),
  556. );
  557. }
  558. return $rtn;
  559. }
  560. /**
  561. * hook_blocks. Returns an array of available blocks offered by this module in this format:
  562. * array(
  563. * delta => "This is the title of the block.",
  564. * ),
  565. * );
  566. *
  567. * Delta can be just about anything machine-readable. Alphanumeric and underscores only.
  568. * Ex: 0, 1, fun_2, etc.
  569. *
  570. */
  571. function content_blocks() {
  572. return array(
  573. "primary" => t("Primary content block"),
  574. );
  575. }
  576. /**
  577. * Called when it is time to render the block in question.
  578. * Expected to return an array which looks like this:
  579. * array(
  580. * "title" => "Some title goes here.",
  581. * "body" => "this is the primary body of the block",
  582. * );
  583. */
  584. function content_render_block($delta) {
  585. $rtn = array();
  586. if ($delta == "primary") {
  587. fp_add_css(fp_get_module_path("content") . "/css/content.css");
  588. $rtn["title"] = t("content");
  589. $rtn["body"] = content_render_content();
  590. }
  591. return $rtn;
  592. }

Functions

Namesort descending Description
content_blocks hook_blocks. Returns an array of available blocks offered by this module in this format: array( delta => "This is the title of the block.", ), );
content_content_load Implementation of content's hook_content_load
content_content_register_content_type Implementation of this module's hook_content_register_content_type.
content_display_content_admin_list Display a list of content for the administrator
content_edit_content_form This form lets the user edit some piece of content
content_edit_content_form_submit Submit handler for the edit content form.
content_get_types Return an array with all the possible content types known to FlightPath
content_handle_delete_content
content_load Load the content from the database and return an array, by calling hook_content_load.
content_menu
content_menu_handle_replacement_pattern This is an implementation of hook_menu_handle_replacement_pattern. It will search for and replace replacement patterns which we are aware of it in $str.
content_perm Implementation of hook_perm
content_render_block Called when it is time to render the block in question. Expected to return an array which looks like this: array( "title" => "Some title goes here.", "body" => "this is the primary body of the block", );
content_render_content Return the HTML rendering the content we have in the database.
content_user_access Custom user access function to determine if the user can add, edit, etc, the content
content_view_content Display the content specified in the GET's cid.
hook_content_load Sample hook for hook_content_load
hook_content_register_content_type Sample hook other modules implement to register a content type.