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

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.