PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/blog/wp-content/themes/extinct/prologue-projects/functions.php

https://bitbucket.org/sergiohzlz/reportaprod
PHP | 1132 lines | 857 code | 198 blank | 77 comment | 157 complexity | fc702024355beb8005711e9fa1ec5401 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Tells us if we are in WordPress.com or not.
  4. **/
  5. if ( !defined( 'IS_WPCOM' ) ) {
  6. define( 'IS_WPCOM', false );
  7. }
  8. /**
  9. * Some special variables used in WordPress.com.
  10. */
  11. if ( IS_WPCOM ) {
  12. $themecolors = array(
  13. 'bg' => 'f5f5f5',
  14. 'border' => 'dddddd',
  15. 'text' => '555555',
  16. 'link' => '21759b'
  17. );
  18. }
  19. $content_width = 488; // pixels
  20. /**
  21. * Register some dependencies at initialisation.
  22. *
  23. * @return void
  24. **/
  25. function pp_init()
  26. {
  27. wp_register_script( 'pp-front', get_bloginfo('template_url') . '/prologue-projects.js', false, '20090218' );
  28. wp_register_style( 'pp-reset-fonts', get_bloginfo('template_url') . '/reset-fonts.css', false, '20090218' );
  29. wp_register_style( 'pp-front', get_bloginfo('template_url') . '/style.css', array('pp-reset-fonts'), '20090218' );
  30. }
  31. add_action( 'init', 'pp_init' );
  32. /**
  33. * Enqueue our dependencies for linking in the html head.
  34. *
  35. * @return void
  36. **/
  37. function pp_head()
  38. {
  39. wp_enqueue_script( 'pp-front' );
  40. wp_enqueue_style( 'pp-front' );
  41. }
  42. add_action( 'wp_head', 'pp_head', 1 );
  43. /**
  44. * Where the bloody hell are ya?
  45. *
  46. * @return string The current URL.
  47. **/
  48. function pp_get_current_url()
  49. {
  50. $schema = is_ssl() ? 'https://' : 'http://';
  51. return $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  52. }
  53. /**
  54. * Get stored options for prologue_projects and merge them with the defaults.
  55. *
  56. * @return array All the options.
  57. **/
  58. function pp_get_options()
  59. {
  60. $defaults = array(
  61. 'category_projects' => false,
  62. 'featured_project' => false,
  63. 'project_data' => array(),
  64. 'projects_sidebars' => false,
  65. 'category_updates' => false,
  66. 'category_tasks' => false,
  67. 'default_task_level' => false,
  68. 'category_questions' => false,
  69. 'default_question_state' => false,
  70. 'author_sidebars' => false
  71. );
  72. $options = get_option( 'prologue_projects' );
  73. return array_merge( $defaults, $options );
  74. }
  75. /**
  76. * Get a single prologue_projects option
  77. *
  78. * @param string $key The key of the option to be retrieved.
  79. * @return mixed The value of the option or boolean false if not set.
  80. **/
  81. function pp_get_option( $key )
  82. {
  83. if ( !$key ) {
  84. return false;
  85. }
  86. $options = pp_get_options();
  87. if ( !isset( $options[$key] ) ) {
  88. return false;
  89. }
  90. return $options[$key];
  91. }
  92. /**
  93. * Shorthand function to retrieve the actual category id of a prologue_projects post type
  94. *
  95. * @param string $type The post type whose category id is to be returned, can be one of "projects", "updates", "tasks" or "questions".
  96. * @return int The category id or false if none is set.
  97. **/
  98. function pp_get_category_id( $type )
  99. {
  100. return pp_get_option( 'category_' . $type );
  101. }
  102. /**
  103. * Allows for template customisation of individual projects by injecting new files named after the project slug into the template hierarchy.
  104. *
  105. * When a request is made for "updates" in the project "foo", WordPress will look for the following files in order:
  106. * 1. updates-foo.php
  107. * 2. updates.php
  108. * 3. index.php
  109. * 4. The originally determined category template, passed as parameter $template.
  110. *
  111. * @param string $template The originally determined category template.
  112. * @return void
  113. **/
  114. function pp_category_template( $template )
  115. {
  116. $requested_category_id = absint( get_query_var( 'cat' ) );
  117. $types = array(
  118. 'projects' => pp_get_category_id( 'projects' ),
  119. 'updates' => pp_get_category_id( 'updates' ),
  120. 'tasks' => pp_get_category_id( 'tasks' ),
  121. 'questions' => pp_get_category_id( 'questions' )
  122. );
  123. foreach ( $types as $_type => $_category_id ) {
  124. if ( !$_category_id ) {
  125. continue;
  126. }
  127. $_category = get_category( absint( $_category_id ) );
  128. if ( !$_category || is_wp_error( $_category ) ) {
  129. continue;
  130. }
  131. if ( $_category_id == $requested_category_id ) {
  132. return locate_template( array(
  133. $_type . '.php',
  134. 'index.php',
  135. $template
  136. ) );
  137. }
  138. $_ids = get_categories( array(
  139. 'child_of' => $_category_id,
  140. 'hide_empty' => false,
  141. 'fields' => 'ids'
  142. ) );
  143. if ( !in_array( $requested_category_id, $_ids ) ) {
  144. continue;
  145. }
  146. $_type_category = get_category( $requested_category_id );
  147. if ( !$_type_category || is_wp_error( $_type_category ) ) {
  148. continue;
  149. }
  150. return locate_template( array(
  151. $_type . '-' . $_type_category->slug . '.php',
  152. $_type . '.php',
  153. 'index.php',
  154. $template
  155. ) );
  156. }
  157. return $template;
  158. }
  159. add_filter( 'category_template', 'pp_category_template' );
  160. /**
  161. * Allows the use of Trac-style shorthand for links to Trac tickets and changesets.
  162. *
  163. * @param string $text The text to be modified.
  164. * @return string The modified text.
  165. **/
  166. function pp_make_tracable( $text )
  167. {
  168. if ( !$text || !preg_match( '@(?:#[a-z0-9]+)|(?:\[[a-z0-9]+\])@i', $text ) ) {
  169. return $text;
  170. }
  171. global $id, $post;
  172. if ( !$category_ids = wp_get_post_categories( $id ) ) {
  173. return $text;
  174. }
  175. $project_tracs = array();
  176. $i = 0;
  177. foreach ( $category_ids as $category_id ) {
  178. $project_data = pp_get_project_data( $category_id );
  179. if ( isset( $project_data['trac'] ) && $project_data['trac'] ) {
  180. $i++;
  181. $project_tracs[$i][0][0] = '#' . preg_quote( $project_data['slug'] ) . '([0-9]+)';
  182. $project_tracs[$i][0][1] = $project_data['trac'] . 'ticket/$1';
  183. $project_tracs[$i][0][2] = '#' . $project_data['slug'] . '$1';
  184. $project_tracs[$i][1][0] = '\[' . preg_quote( $project_data['slug'] ) . '([0-9]+)\]';
  185. $project_tracs[$i][1][1] = $project_data['trac'] . 'changeset/$1';
  186. $project_tracs[$i][1][2] = '[' . $project_data['slug'] . '$1]';
  187. if ( isset( $project_data['intertrac'] ) && $project_data['intertrac'] ) {
  188. $project_tracs[$i][2][0] = '#' . preg_quote( $project_data['intertrac'] ) . '([0-9]+)';
  189. $project_tracs[$i][2][1] = $project_data['trac'] . 'ticket/$1';
  190. $project_tracs[$i][2][2] = '#' . $project_data['intertrac'] . '$1';
  191. $project_tracs[$i][3][0] = '\[' . preg_quote( $project_data['intertrac'] ) . '([0-9]+)\]';
  192. $project_tracs[$i][3][1] = $project_data['trac'] . 'changeset/$1';
  193. $project_tracs[$i][3][2] = '[' . $project_data['intertrac'] . '$1]';
  194. }
  195. }
  196. }
  197. if ( !count( $project_tracs ) ) {
  198. return $text;
  199. }
  200. if ( count( $project_tracs ) === 1 ) {
  201. $project_tracs[0][0][0] = '#([0-9]+)';
  202. $project_tracs[0][0][1] = $project_tracs[1][0][1];
  203. $project_tracs[0][0][2] = '#$1';
  204. $project_tracs[0][1][0] = '\[([0-9]+)\]';
  205. $project_tracs[0][1][1] = $project_tracs[1][1][1];
  206. $project_tracs[0][1][2] = '[$1]';
  207. }
  208. ksort( $project_tracs );
  209. foreach ( $project_tracs as $pairs ) {
  210. foreach ( $pairs as $pair ) {
  211. $text = preg_replace( '@' . $pair[0] . '@', '<a href="' . $pair[1] . '">' . $pair[2] . '</a>', $text );
  212. }
  213. }
  214. return $text;
  215. }
  216. add_filter( 'the_content', 'pp_make_tracable', 1 );
  217. add_filter( 'the_content', 'make_clickable' );
  218. /**
  219. * Get the meta data of a given project.
  220. *
  221. * @param integer $category_id The category id of the project.
  222. * @param string $type Optional. The specific meta data to get. Default is "all", which retrieves all meta data.
  223. * @return mixed The projects meta data in an associative array or the specific data as requested with the $type parameter.
  224. **/
  225. function pp_get_project_data( $category_id = 0, $type = 'all', $context = '' )
  226. {
  227. if ( !$category_id ) {
  228. global $cat;
  229. $category_id = $cat;
  230. }
  231. if ( !$category_id ) {
  232. return false;
  233. }
  234. if ( is_object( $category_id ) && !is_wp_error( $category_id ) ) {
  235. $category = $category_id;
  236. $category_id = $category->cat_ID;
  237. }
  238. if ( !$context && $cache = wp_cache_get( $category_id, 'pp_project_data' ) ) {
  239. if ( 'all' === $type ) {
  240. return $cache;
  241. }
  242. if ( !isset( $cache[$type] ) ) {
  243. return false;
  244. }
  245. return $cache[$type];
  246. }
  247. if ( !isset( $category ) ) {
  248. $category = get_category( $category_id );
  249. }
  250. if ( !$category || is_wp_error( $category ) ) {
  251. return false;
  252. }
  253. $data = array();
  254. $data['id'] = $category->cat_ID;
  255. $data['name'] = $category->name;
  256. $data['parent_id'] = $category->parent;
  257. $data['slug'] = $category->slug;
  258. $data['url'] = get_category_link( $category->cat_ID );
  259. $data['link'] = '<a href="' . attribute_escape( $data['url'] ) . '">' . $data['name'] . '</a>';
  260. $data['description'] = $category->description;
  261. $data['logo'] = '';
  262. $data['website'] = '';
  263. $data['blog'] = '';
  264. $data['svn'] = '';
  265. $data['trac'] = '';
  266. $data['intertrac'] = '';
  267. $data['activity'] = array();
  268. $data['overheard'] = array();
  269. if ( $meta = get_option( 'pp_project_meta_' . $data['id'] ) ) {
  270. foreach ( $meta as $key => $value ) {
  271. if ( in_array( $key, array( 'intertrac', 'logo' ) ) ) {
  272. $data[$key] = $value;
  273. } elseif ( in_array( $key, array( 'activity', 'overheard' ) ) && $value ) {
  274. $data[$key] = array_merge( $data[$key], $value );
  275. } elseif ( $value ) {
  276. $data[$key] = rtrim( $value, '/' ) . '/';
  277. }
  278. }
  279. if ( $data['trac'] && !$context ) {
  280. $data['activity'][] = $data['trac'] . 'timeline?milestone=on&ticket=on&changeset=on&wiki=on&format=rss&max=20';
  281. }
  282. }
  283. if ( !$context ) {
  284. wp_cache_add( $category_id, $data, 'pp_project_data' );
  285. }
  286. if ( 'all' === $type ) {
  287. return $data;
  288. }
  289. if ( !isset( $data[$type] ) ) {
  290. return false;
  291. }
  292. return $data[$type];
  293. }
  294. /**
  295. * Callback to clean out the specific project data cache when categories are edited.
  296. *
  297. * @param $category_id The category id of the project.
  298. * @return boolean True if the cache was emptied.
  299. **/
  300. function pp_delete_project_data_cache( $category_id )
  301. {
  302. if ( !$category_id ) {
  303. return false;
  304. }
  305. return wp_cache_delete( $category_id, 'pp_project_data' );
  306. }
  307. add_action( 'delete_category', 'pp_delete_project_data_cache', 10, 1 );
  308. add_action( 'edit_category', 'pp_delete_project_data_cache', 10, 1 );
  309. /**
  310. * Find out if the given category is a project.
  311. *
  312. * @param integer $category_id The id of the category.
  313. * @return boolean True if it is a project, otherwise false.
  314. **/
  315. function pp_is_project( $category_id = 0 )
  316. {
  317. $categories = pp_get_projects();
  318. if ( !$categories || count( $categories ) < 1 ) {
  319. return false;
  320. }
  321. if ( !$category_id = pp_get_project_data( $category_id, 'id' ) ) {
  322. return false;
  323. }
  324. $is_project = false;
  325. foreach ( $categories as $category ) {
  326. if ( $category_id == $category->cat_ID ) {
  327. $is_project = true;
  328. break;
  329. }
  330. }
  331. return $is_project;
  332. }
  333. function pp_get_projects( $parent_id = 0 )
  334. {
  335. if ( $parent_id && !pp_is_project( $parent_id ) ) { // Narrowly avoiding circular logic here :)
  336. return;
  337. } elseif ( !$parent_id && !$parent_id = pp_get_category_id( 'projects' ) ) {
  338. return;
  339. }
  340. $categories = get_categories( array(
  341. 'child_of' => $parent_id,
  342. 'hierarchical' => 1,
  343. 'hide_empty' => 0
  344. ) );
  345. return $categories;
  346. }
  347. function pp_get_question_statuses()
  348. {
  349. if ( !$parent_id = pp_get_category_id( 'questions' ) ) {
  350. return;
  351. }
  352. $categories = get_categories( array(
  353. 'child_of' => $parent_id,
  354. 'hide_empty' => 0
  355. ) );
  356. return $categories;
  357. }
  358. function pp_is_question_status( $category_id )
  359. {
  360. if ( !$category_id ) {
  361. return false;
  362. }
  363. $categories = pp_get_question_statuses();
  364. if ( !$categories || count( $categories ) < 1 ) {
  365. return false;
  366. }
  367. $is_status = false;
  368. foreach ( $categories as $category ) {
  369. if ( $category_id == $category->cat_ID ) {
  370. $is_status = true;
  371. break;
  372. }
  373. }
  374. return $is_status;
  375. }
  376. function pp_get_project_members( $category_id = 0 )
  377. {
  378. $project_id = pp_get_project_data( $category_id, 'id' );
  379. if ( !$project_id ) {
  380. return false;
  381. }
  382. global $wpdb, $blog_id;
  383. $query = "SELECT `user_id`, `user_login`, `user_nicename`, `display_name`, `user_email`, `meta_value`
  384. FROM `" . $wpdb->users . "`, `" . $wpdb->usermeta . "`
  385. WHERE `" . $wpdb->users . "`.`ID` = `" . $wpdb->usermeta . "`.`user_id`
  386. AND `meta_key` = 'prologue_projects_" . $blog_id . "'
  387. AND `meta_value` LIKE '%i:" . (int) $project_id . ";a:2:{i:0;i:1;%'
  388. ORDER BY `" . $wpdb->users . "`.`display_name`;";
  389. $members = $wpdb->get_results( $query, ARRAY_A );
  390. $_members = array();
  391. if ( $members && count( $members ) ) {
  392. foreach ( $members as $member ) {
  393. $_member = $member;
  394. $_member['projects'] = maybe_unserialize( $member['meta_value'] );
  395. unset( $_member['meta_value'] );
  396. $_member['project_role'] = strip_tags( trim( wp_filter_kses( wp_specialchars( $_member['projects'][$category_id][1] ) ) ) );
  397. unset( $_member['projects'] );
  398. $_members[] = $_member;
  399. }
  400. }
  401. return $_members;
  402. }
  403. function pp_get_user_projects( $user_id = 0 )
  404. {
  405. if ( !$user = new WP_User( $user_id ) ) {
  406. return false;
  407. }
  408. global $blog_id;
  409. $meta = 'prologue_projects_' . $blog_id;
  410. if ( !isset( $user->$meta ) || !$user->$meta || !is_array( $user->$meta ) ) {
  411. return false;
  412. }
  413. $projects = array();
  414. foreach ( $user->$meta as $project_id => $project_settings ) {
  415. if ( $project_settings[0] ) {
  416. $projects[$project_id] = $project_settings[1];
  417. }
  418. }
  419. if ( !count( $projects ) ) {
  420. return false;
  421. }
  422. return $projects;
  423. }
  424. /* Template */
  425. function pp_all_projects_rss()
  426. {
  427. if ( !$url = get_feed_link() ) {
  428. return;
  429. }
  430. $r = '<a ';
  431. $r .= 'id="pp-all-projects-rss" ';
  432. $r .= 'class="pp-all-projects-rss" ';
  433. $r .= 'href="' . $url . '">';
  434. $r .= __( 'RSS', 'prologue-projects' );
  435. $r .= '</a>';
  436. echo $r;
  437. }
  438. function pp_project_rss( $category_id = 0 )
  439. {
  440. if ( !$category_id = pp_get_project_data( $category_id, 'id' ) ) {
  441. return;
  442. }
  443. if ( !$url = get_category_feed_link( $category_id ) ) {
  444. return;
  445. }
  446. $r = '<a ';
  447. $r .= 'id="pp-project-rss-' . $data['slug'] . '" ';
  448. $r .= 'class="pp-project-rss" ';
  449. $r .= 'href="' . $url . '">';
  450. $r .= __( 'RSS', 'prologue-projects' );
  451. $r .= '</a>';
  452. echo $r;
  453. }
  454. function pp_project_logo( $category_id = 0 )
  455. {
  456. if ( !$data = pp_get_project_data( $category_id ) ) {
  457. return;
  458. }
  459. if ( !isset( $data['logo'] ) || !$data['logo'] ) {
  460. return;
  461. }
  462. if ( !parse_url( $data['logo'] ) ) {
  463. return;
  464. }
  465. $r = '<img ';
  466. $r .= 'id="pp-project-logo-' . $data['slug'] . '" ';
  467. $r .= 'class="pp-project-logo" ';
  468. $r .= 'src="' . $data['logo'] . '" ';
  469. $r .= 'alt="' . __( 'Project logo', 'prologue-projects' ) . '" />';
  470. echo $r;
  471. }
  472. function pp_project_links( $category_id = 0 )
  473. {
  474. if ( !$data = pp_get_project_data( $category_id ) ) {
  475. return;
  476. }
  477. $r = '<ul id="pp-project-links-' . attribute_escape( $data['slug'] ) . '" class="pp-project-links">';
  478. if ( isset( $data['website'] ) && $data['website'] ) {
  479. $r .= '<li><a href="' . attribute_escape( $data['website'] ) . '">' . __('Website', 'prologue-projects') . '</a></li>' . "\n";
  480. }
  481. if ( isset( $data['blog'] ) && $data['blog'] ) {
  482. $r .= '<li><a href="' . attribute_escape( $data['blog'] ) . '">' . __('Blog', 'prologue-projects') . '</a></li>' . "\n";
  483. }
  484. if ( isset( $data['trac'] ) && $data['trac'] ) {
  485. $trac = attribute_escape( $data['trac'] );
  486. $r .= '<li><a href="' . $trac . '">' . __( 'Trac', 'prologue-projects' ) . '</a></li>' . "\n";
  487. $r .= '<li><a href="' . $trac . 'newticket/">' . __( 'Add Trac ticket', 'prologue-projects' ) . '</a></li>' . "\n";
  488. $r .= '<li><a href="' . $trac . 'browser/">' . __( 'Browse source', 'prologue-projects' ) . '</a></li>' . "\n";
  489. }
  490. if ( isset( $data['svn'] ) && $data['svn'] ) {
  491. $r .= '<li><a href="' . attribute_escape( $data['svn'] ) . '">' . __('Subversion', 'prologue-projects') . '</a></li>' . "\n";
  492. }
  493. $r .= '</ul>';
  494. echo $r;
  495. }
  496. function pp_get_project_base_link()
  497. {
  498. $project_category = get_category( pp_get_category_id( 'projects' ) );
  499. if ( !$project_category || is_wp_error( $project_category ) ) {
  500. return false;
  501. }
  502. $project_link = get_category_link( $project_category );
  503. if ( !$project_link || is_wp_error( $project_link ) ) {
  504. return false;
  505. }
  506. return '<a href="' . $project_link . '">' . $project_category->name . '</a>';
  507. }
  508. function _pp_prepend_parent_link_to_breadcrumbs( $breadcrumbs, $category_id = 0 )
  509. {
  510. if ( $category_id == pp_get_category_id( 'projects' ) ) {
  511. return $breadcrumbs;
  512. }
  513. if ( !$data = pp_get_project_data( $category_id ) ) {
  514. return $breadcrumbs;
  515. }
  516. $category_id = $data['id'];
  517. $url = $data['url'];
  518. if ( isset( $_GET['tasks'] ) ) {
  519. $url = $url . '?tasks';
  520. } elseif ( isset( $_GET['questions'] ) ) {
  521. $url = $url . '?questions';
  522. }
  523. $link = '<a href="' . attribute_escape( $url ) . '">' . $data['name'] . '</a>';
  524. array_unshift( $breadcrumbs, $link );
  525. if ( (int) $data['id'] === (int) pp_get_category_id( 'projects' ) ) {
  526. return $breadcrumbs;
  527. }
  528. return _pp_prepend_parent_link_to_breadcrumbs( $breadcrumbs, $data['parent_id'] );
  529. }
  530. function pp_project_breadcrumbs( $category_id = 0 )
  531. {
  532. $data = pp_get_project_data( $category_id );
  533. $breadcrumbs = array();
  534. if ( $data ) {
  535. $breadcrumbs = _pp_prepend_parent_link_to_breadcrumbs( $breadcrumbs, $data['id'] );
  536. }
  537. array_unshift( $breadcrumbs, '<a href="' . attribute_escape( get_bloginfo( 'url' ) ) . '">' . __( 'Home', 'prologue-projects' ) . '</a>' );
  538. $r = '<ul id="pp-project-breadcrumbs-' . $data['slug'] . '" class="pp-project-breadcrumbs">' . "\n";
  539. foreach ( $breadcrumbs as $breadcrumb ) {
  540. $r .= '<li>' . $breadcrumb . '</li>' . "\n";
  541. }
  542. if ( $data ) {
  543. $sub_projects = get_categories( array(
  544. 'parent' => $data['id'],
  545. 'hide_empty' => false
  546. ) );
  547. }
  548. if ( $sub_projects && !is_wp_error( $sub_projects ) ) {
  549. $r .= '<li class="pp-sub-projects"><form><label for="pp-sub-project-selector">' . __( 'Select a sub-project', 'prologue-projects' ) . '</label><select name="pp-sub-project-selector" onchange="pp_go(this);">';
  550. $r .= '<option value=""></option>';
  551. foreach ( $sub_projects as $sub_project ) {
  552. $sub_project_url = pp_get_project_data( $sub_project, 'url' );
  553. if ( isset( $_GET['tasks'] ) ) {
  554. $sub_project_url = $sub_project_url . '?tasks';
  555. } elseif ( isset( $_GET['questions'] ) ) {
  556. $sub_project_url = $sub_project_url . '?questions';
  557. }
  558. $r .= '<option value="' . attribute_escape( $sub_project_url ) . '">' . wp_specialchars( pp_get_project_data( $sub_project, 'name' ) ) . '</option>';
  559. }
  560. $r .= '</select></form></li>' . "\n";
  561. }
  562. $r .= '</ul>' . "\n";
  563. echo $r;
  564. }
  565. function pp_project_name( $category_id = 0 )
  566. {
  567. echo wp_specialchars( pp_get_project_data( $category_id, 'name' ) );
  568. }
  569. function pp_project_description( $category_id = 0 )
  570. {
  571. echo wpautop( wp_specialchars( pp_get_project_data( $category_id, 'description' ) ) );
  572. }
  573. function pp_project_website( $category_id = 0 )
  574. {
  575. echo '<a href="' . attribute_escape( pp_get_project_data( $category_id, 'website' ) ) . '">' . wp_specialchars( pp_get_project_data( $category_id, 'name' ) ) . '</a>';
  576. }
  577. function pp_get_project_activity( $category_id = 0 )
  578. {
  579. if ( !$data = pp_get_project_data( $category_id ) ) {
  580. return;
  581. }
  582. if ( !isset( $data['activity'] ) || !$data['activity'] ) {
  583. return;
  584. }
  585. require_once( ABSPATH . WPINC . '/rss.php' );
  586. $feeds = array();
  587. foreach ( $data['activity'] as $feed_url ) {
  588. $feeds[] = fetch_rss( $feed_url );
  589. }
  590. $items = array();
  591. foreach ( $feeds as $feed ) {
  592. if ( !isset( $feed->items ) ) {
  593. continue;
  594. }
  595. foreach ( $feed->items as $item ) {
  596. $time = strtotime( $item['pubdate'] );
  597. $item['time'] = $time;
  598. if ( $parsed = parse_url( $item['link'] ) ) {
  599. $item['domain'] = $parsed['host'];
  600. }
  601. $items[$time] = $item;
  602. }
  603. }
  604. krsort( $items, SORT_NUMERIC );
  605. $r .= '<ul id="pp-project-activity-' . $data['slug'] . '" class="pp-project-activity"%s>';
  606. $count = 0;
  607. foreach ( $items as $item ) {
  608. $count++;
  609. if ( $count === 10 ) {
  610. break;
  611. }
  612. $datetime = sprintf( __( '%1$s on %2$s' ), date_i18n( get_option('time_format'), $item['time'] ), date_i18n( get_option( 'date_format' ), $item['time'] ) );
  613. $r .= '<li>' . wp_specialchars( $datetime ) . '<div><a href="' . attribute_escape( $item['link'] ) . '">' . wp_specialchars( strip_tags( html_entity_decode( $item['title'], ENT_QUOTES ) ) ) . '</a> <span class="domain">@' . wp_specialchars( $item['domain'] ) . '</span></div></li>';
  614. }
  615. $r .= '</ul>';
  616. return $r;
  617. }
  618. function pp_get_project_overheard( $category_id = 0 )
  619. {
  620. if ( !$data = pp_get_project_data( $category_id ) ) {
  621. return;
  622. }
  623. if ( !isset($data['overheard']) || !$data['overheard'] ) {
  624. return;
  625. }
  626. require_once( ABSPATH . WPINC . '/rss.php' );
  627. $feeds = array();
  628. foreach ( $data['overheard'] as $feed_url ) {
  629. $feeds[] = fetch_rss( $feed_url );
  630. }
  631. $items = array();
  632. foreach ( $feeds as $feed ) {
  633. if ( !isset( $feed->items ) ) {
  634. continue;
  635. }
  636. foreach ( $feed->items as $item ) {
  637. $time = strtotime( $item['dc']['date'] );
  638. $item['time'] = $time;
  639. if ( $parsed = parse_url( $item['link'] ) ) {
  640. $item['domain'] = $parsed['host'];
  641. }
  642. $items[$time] = $item;
  643. }
  644. }
  645. krsort( $items, SORT_NUMERIC );
  646. $r .= '<ul id="pp-project-overheard-' . $data['slug'] . '" class="pp-project-overheard"%s>';
  647. $count = 0;
  648. foreach ( $items as $item ) {
  649. $count++;
  650. if ( $count === 10 ) {
  651. break;
  652. }
  653. $datetime = sprintf( __( '%1$s on %2$s' ), date_i18n( get_option('time_format'), $item['time'] ), date_i18n( get_option( 'date_format' ), $item['time'] ) );
  654. $r .= '<li>' . wp_specialchars( $datetime ) . '<div><a href="' . attribute_escape( $item['link'] ) . '">' . wp_specialchars( strip_tags( html_entity_decode( $item['title'], ENT_QUOTES ) ) ) . '</a> <span class="domain">@' . wp_specialchars( $item['domain'] ) . '</span></div></li>';
  655. }
  656. $r .= '</ul>';
  657. return $r;
  658. }
  659. function pp_project_feeds( $category_id = 0 )
  660. {
  661. if ( !$data = pp_get_project_data( $category_id ) ) {
  662. return;
  663. }
  664. $r_nav = array(
  665. 'activity' => '',
  666. 'overheard' => ''
  667. );
  668. $r = array(
  669. 'activity' => '',
  670. 'overheard' => ''
  671. );
  672. if ( $activity = pp_get_project_activity( $category_id ) ) {
  673. $r_nav['activity'] = '<li%s>%s' . __('Recent activity', 'prologue-projects') . '%s</li>' . "\n";
  674. $r['activity'] = $activity;
  675. }
  676. if ( $overheard = pp_get_project_overheard( $category_id ) ) {
  677. $r_nav['overheard'] = '<li%s>%s' . __('Overheard', 'prologue-projects') . '%s</li>' . "\n";
  678. $r['overheard'] = $overheard;
  679. }
  680. if ( $activity ) {
  681. if ( $overheard ) {
  682. $r_nav['activity'] = sprintf( $r_nav['activity'], ' class="active"', '<a href="javascript:void(0);" onclick="pp_switch_feeds(\'pp-project-feeds-nav-' . $data['slug'] . '\', this, \'pp-project-activity-' . $data['slug'] . '\', \'pp-project-overheard-' . $data['slug'] . '\')">', '</a>' );
  683. $r_nav['overheard'] = sprintf( $r_nav['overheard'], '', '<a href="javascript:void(0);" onclick="pp_switch_feeds(\'pp-project-feeds-nav-' . $data['slug'] . '\', this, \'pp-project-overheard-' . $data['slug'] . '\', \'pp-project-activity-' . $data['slug'] . '\')">', '</a>' );
  684. $r['overheard'] = sprintf( $r['overheard'], ' style="display:none;"' );
  685. } else {
  686. $r_nav['activity'] = sprintf( $r_nav['activity'], ' class="active lonely"', '', '' );
  687. $r['activity'] = sprintf( $r['activity'], '' );
  688. }
  689. } elseif ( $overheard ) {
  690. $r_nav['overheard'] = sprintf( $r_nav['overheard'], ' class="active lonely"', '', '' );
  691. $r['overheard'] = sprintf( $r['overheard'], '' );
  692. } else {
  693. return;
  694. }
  695. echo '<ul id="pp-project-feeds-nav-' . $data['slug'] . '" class="pp-project-feeds-nav">' . $r_nav['activity'] . $r_nav['overheard'] . '</ul><div class="pp-project-feeds">' . $r['activity'] . $r['overheard'] . '</div>';
  696. }
  697. class PP_Walker_Category_Checklist extends Walker {
  698. var $tree_type = 'category';
  699. var $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); //TODO: decouple this
  700. function start_lvl(&$output, $depth, $args) {
  701. $indent = str_repeat("\t", $depth);
  702. $output .= "$indent<ul class='children'>\n";
  703. }
  704. function end_lvl(&$output, $depth, $args) {
  705. $indent = str_repeat("\t", $depth);
  706. $output .= "$indent</ul>\n";
  707. }
  708. function start_el(&$output, $category, $depth, $args) {
  709. extract($args);
  710. $output .= "\n<li id='category-$category->term_id'>" . '<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $args['input_name'] . '[' . $category->term_id . ']" id="in-category-' . $category->term_id . '"' . ( in_array( $category->term_id, $selected_cats ) ? ' checked="checked"' : "" ) . '/> ' . wp_specialchars( apply_filters( 'the_category', $category->name ) ) . '</label>';
  711. if ( isset( $args['user_project_role'] ) ) {
  712. $output .= '<label>' . __(' &mdash; role', 'prologue-projects') . ' <input name="' . $args['input_name'] . '_role[' . $category->term_id . ']" type="text" value="' . attribute_escape( $args['user_project_role'][$category->term_id][1] ) . '" /></label>';
  713. }
  714. }
  715. function end_el( &$output, $category, $depth, $args ) {
  716. $output .= '</li>' . "\n";
  717. }
  718. }
  719. function pp_project_checklist( $checked = false, $input_name = 'post_category' )
  720. {
  721. $categories = pp_get_projects();
  722. $walker = new PP_Walker_Category_Checklist();
  723. $args = array();
  724. if ( $checked ) {
  725. $checked = (array) $checked;
  726. $args['selected_cats'] = $checked;
  727. } else {
  728. $args['selected_cats'] = array( absint( get_query_var( 'cat' ) ) );
  729. }
  730. if ( !$input_name ) {
  731. $input_name = 'post_category';
  732. }
  733. $args['input_name'] = $input_name;
  734. echo '<ul class="pp-update-categories">';
  735. echo call_user_func_array( array( &$walker, 'walk' ), array( $categories, 0, $args ) );
  736. echo '</ul>';
  737. }
  738. function pp_project_and_role_checklist( $user_id = 0, $checked = false, $input_name = 'post_category' )
  739. {
  740. $categories = pp_get_projects();
  741. $walker = new PP_Walker_Category_Checklist();
  742. $args = array();
  743. if ( $checked ) {
  744. $checked = (array) $checked;
  745. $args['selected_cats'] = $checked;
  746. } else {
  747. $args['selected_cats'] = array( absint( get_query_var( 'cat' ) ) );
  748. }
  749. if ( !$input_name ) {
  750. $input_name = 'post_category';
  751. }
  752. $args['input_name'] = $input_name;
  753. global $blog_id;
  754. $args['user_project_role'] = get_usermeta( $user_id, 'prologue_projects_' . $blog_id );
  755. $args['user_project_role'] = $args['user_project_role'] ? $args['user_project_role'] : array();
  756. echo '<ul class="pp-update-categories">';
  757. echo call_user_func_array( array( &$walker, 'walk' ), array( $categories, 0, $args ) );
  758. echo '</ul>';
  759. }
  760. function pp_author_title()
  761. {
  762. global $wp_query;
  763. if ( !isset( $wp_query->query_vars['author'] ) ) {
  764. return;
  765. }
  766. echo get_author_name( $wp_query->query_vars['author'] );
  767. }
  768. function pp_author_rss()
  769. {
  770. global $wp_query;
  771. if ( !isset( $wp_query->query_vars['author'] ) ) {
  772. return;
  773. }
  774. if ( !$url = get_author_feed_link( $wp_query->query_vars['author'] ) ) {
  775. return;
  776. }
  777. $r = '<a ';
  778. $r .= 'id="pp-project-rss-' . $data['slug'] . '" ';
  779. $r .= 'class="pp-project-rss" ';
  780. $r .= 'href="' . attribute_escape( $url ) . '">';
  781. $r .= __( 'RSS', 'prologue-projects' );
  782. $r .= '</a>';
  783. echo $r;
  784. }
  785. function pp_the_projects( $before = 'Projects: ', $sep = ', ', $after = '' )
  786. {
  787. $terms = get_the_terms( 0, 'category' );
  788. if ( is_wp_error( $terms ) ) {
  789. return;
  790. }
  791. if ( empty( $terms ) ) {
  792. return;
  793. }
  794. $term_links = array();
  795. foreach ( $terms as $term ) {
  796. if ( !pp_is_project( $term->term_id ) ) {
  797. continue;
  798. }
  799. $link = get_term_link( $term, 'category' );
  800. if ( is_wp_error( $link ) ) {
  801. continue;
  802. }
  803. $term_links[] = '<a href="' . $link . '" rel="tag">' . $term->name . '</a>';
  804. }
  805. if ( !count( $term_links ) ) {
  806. return;
  807. }
  808. echo $before . join( $sep, $term_links ) . $after;
  809. }
  810. function pp_the_question_status( $before = '', $pattern = '%s', $after = '' )
  811. {
  812. $terms = get_the_terms( 0, 'category' );
  813. if ( is_wp_error( $terms ) ) {
  814. return;
  815. }
  816. if ( empty( $terms ) ) {
  817. return;
  818. }
  819. $status = false;
  820. foreach ( $terms as $term ) {
  821. if ( !pp_is_question_status( $term->term_id ) ) {
  822. continue;
  823. }
  824. $link = get_term_link( $term, 'category' );
  825. if ( is_wp_error( $link ) ) {
  826. continue;
  827. }
  828. $status = $term->name;
  829. break;
  830. }
  831. if ( !$status ) {
  832. return;
  833. }
  834. echo $before . sprintf( $pattern, $status ) . $after;
  835. }
  836. function pp_page_navigation()
  837. {
  838. $newer = get_previous_posts_link( __( '&#x2190; Newer Posts', 'prologue-projects' ) );
  839. $older = get_next_posts_link( __( 'Older Posts &#x2192;', 'prologue-projects' ) );
  840. if ( !$newer && !$older ) {
  841. return;
  842. }
  843. $r = '<ul id="pp-page-navigation">';
  844. if ( $newer ) {
  845. $r .= '<li class="newer">' . $newer . '</li>';
  846. }
  847. if ( $older ) {
  848. $r .= '<li class="older">' . $older . '</li>';
  849. }
  850. $r .= '</ul><div class="pp-clear"></div>';
  851. echo $r;
  852. }
  853. function pp_maybe_insert_post()
  854. {
  855. if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'post' ) {
  856. if ( ! is_user_logged_in() ) {
  857. auth_redirect();
  858. }
  859. if( !current_user_can( 'publish_posts' ) ) {
  860. $goback = add_query_arg( 'result', -2, wp_get_referer() );
  861. wp_redirect( $goback );
  862. exit;
  863. }
  864. check_admin_referer( 'pp-update' );
  865. $user_id = $current_user->user_id;
  866. $post_content = $_POST['posttext'];
  867. $tags = $_POST['tags'];
  868. $char_limit = 40;
  869. $post_title = trim( strip_tags( $post_content ) );
  870. if( strlen( $post_title ) > $char_limit ) {
  871. $post_title = substr( $post_title, 0, $char_limit ) . ' ... ';
  872. }
  873. $categories = isset( $_POST['post_category'] ) ? $_POST['post_category'] : array();
  874. if ( !is_array( $categories ) ) {
  875. $categories = array( $categories );
  876. }
  877. if ( isset( $_POST['task_level'] ) ) {
  878. $categories[] = (int) $_POST['task_level'];
  879. }
  880. $options = pp_get_options();
  881. $category_updates_id = $options['category_updates'];
  882. $category_tasks_id = $options['category_tasks'];
  883. $category_questions_id = $options['category_questions'];
  884. $category_default_questions_status = $options['default_question_state'];
  885. if ( isset( $_GET['tasks'] ) ) {
  886. $type = 'tasks';
  887. } elseif ( isset( $_GET['questions'] ) ) {
  888. $type = 'questions';
  889. } else {
  890. $type = 'updates';
  891. }
  892. switch ( $type ) {
  893. case 'questions':
  894. if ( $category_questions_id ) {
  895. $categories[] = $category_questions_id;
  896. $categories[] = $category_default_questions_status;
  897. }
  898. break;
  899. case 'tasks':
  900. if ( $category_tasks_id ) {
  901. $categories[] = $category_tasks_id;
  902. }
  903. break;
  904. case 'updates':
  905. default:
  906. if ( $category_updates_id ) {
  907. $categories[] = $category_updates_id;
  908. }
  909. break;
  910. }
  911. $categories = array_filter($categories);
  912. $post_id = wp_insert_post( array(
  913. 'post_author' => $user_id,
  914. 'post_title' => $post_title,
  915. 'post_content' => $post_content,
  916. 'tags_input' => $tags,
  917. 'post_status' => 'publish',
  918. 'post_category' => $categories
  919. ) );
  920. if ( !$post_id ) {
  921. $goback = add_query_arg( 'result', -1, wp_get_referer() );
  922. } else {
  923. $goback = add_query_arg( 'result', $post_id, wp_get_referer() );
  924. }
  925. wp_redirect( $goback );
  926. exit;
  927. }
  928. }
  929. require_once( 'functions-sidebars.php' );
  930. // We can leave these out if we are not in the admin area
  931. if ( defined( 'WP_ADMIN' ) && WP_ADMIN ) {
  932. require_once( 'functions-admin.php' );
  933. }
  934. ?>