Posts 2 Posts - Version 0.5.1

Version Description

  • fixed fatal error on Menus screen
Download this release

Release Info

Developer scribu
Plugin Icon wp plugin Posts 2 Posts
Version 0.5.1
Comparing to
See all releases

Code changes from version 0.4 to 0.5.1

api.php CHANGED
@@ -67,13 +67,13 @@ function p2p_disconnect( $from, $to, $data = array() ) {
67
  *
68
  * @return array( p2p_id => post_id )
69
  */
70
- function p2p_get_connected( $post_id, $direction = 'to', $data = array() ) {
71
- if ( 'both' == $direction ) {
 
 
72
  $to = P2P_Connections::get( $post_id, 'to', $data );
73
  $from = P2P_Connections::get( $post_id, 'from', $data );
74
  $ids = array_merge( $to, array_diff( $from, $to ) );
75
- } else {
76
- $ids = P2P_Connections::get( $post_id, $direction, $data );
77
  }
78
 
79
  return $ids;
@@ -109,10 +109,10 @@ function p2p_delete_connection( $p2p_id ) {
109
  class P2P_Query {
110
 
111
  function init() {
112
- add_filter( 'posts_where', array( __CLASS__, 'posts_where' ), 10, 2 );
113
  }
114
 
115
- function posts_where( $where, $wp_query ) {
116
  global $wpdb;
117
 
118
  $map = array(
@@ -122,12 +122,61 @@ class P2P_Query {
122
  );
123
 
124
  foreach ( $map as $qv => $direction ) {
125
- if ( $id = $wp_query->get( $qv ) ) {
126
- $where .= " AND $wpdb->posts.ID IN ( " . implode( ',', p2p_get_connected( $id, $direction ) ) . " )";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  }
128
  }
129
 
130
- return $where;
131
  }
132
  }
133
 
67
  *
68
  * @return array( p2p_id => post_id )
69
  */
70
+ function p2p_get_connected( $post_id, $direction = 'both', $data = array() ) {
71
+ if ( in_array( $direction, array( 'to', 'from' ) ) ) {
72
+ $ids = P2P_Connections::get( $post_id, $direction, $data );
73
+ } else {
74
  $to = P2P_Connections::get( $post_id, 'to', $data );
75
  $from = P2P_Connections::get( $post_id, 'from', $data );
76
  $ids = array_merge( $to, array_diff( $from, $to ) );
 
 
77
  }
78
 
79
  return $ids;
109
  class P2P_Query {
110
 
111
  function init() {
112
+ new scbQueryManipulation( array( __CLASS__, 'query' ), false );
113
  }
114
 
115
+ function query( $clauses, $wp_query ) {
116
  global $wpdb;
117
 
118
  $map = array(
122
  );
123
 
124
  foreach ( $map as $qv => $direction ) {
125
+ $search = $wp_query->get( $qv );
126
+ if ( !empty($search) )
127
+ break;
128
+ }
129
+
130
+ if ( empty( $search ) )
131
+ return $clauses;
132
+
133
+ $clauses['fields'] .= ", $wpdb->p2p.p2p_id";
134
+
135
+ $groupby = "{$wpdb->posts}.ID";
136
+ if ( false === strpos( $clauses['groupby'], $groupby ) ) {
137
+ if ( empty( $clauses['groupby'] ) )
138
+ $clauses['groupby'] = $groupby;
139
+ else
140
+ $clauses['groupby'] .= ",$groupby";
141
+ }
142
+
143
+ switch ( $direction ) {
144
+ case 'from':
145
+ $clauses['join'] .= " INNER JOIN $wpdb->p2p ON ($wpdb->posts.ID = $wpdb->p2p.p2p_to)";
146
+ break;
147
+ case 'to':
148
+ $clauses['join'] .= " INNER JOIN $wpdb->p2p ON ($wpdb->posts.ID = $wpdb->p2p.p2p_from)";
149
+ break;
150
+ case 'both':
151
+ $clauses['join'] .= " INNER JOIN $wpdb->p2p ON ($wpdb->posts.ID = $wpdb->p2p.p2p_to OR $wpdb->posts.ID = $wpdb->p2p.p2p_from)";
152
+ break;
153
+ }
154
+
155
+ if ( 'any' != $search ) {
156
+ $search = absint( $search );
157
+
158
+ switch ( $direction ) {
159
+ case 'from':
160
+ $clauses['where'] .= " AND $wpdb->p2p.p2p_from = $search";
161
+ break;
162
+ case 'to':
163
+ $clauses['where'] .= " AND $wpdb->p2p.p2p_to = $search";
164
+ break;
165
+ case 'both':
166
+ $clauses['where'] .= " AND ($wpdb->p2p.p2p_to = $search OR $wpdb->p2p.p2p_from = $search)";
167
+ break;
168
+ }
169
+ }
170
+
171
+ $connected_meta = $wp_query->get('connected_meta');
172
+ if ( !empty( $connected_meta ) ) {
173
+ $meta_clauses = _p2p_meta_sql_helper( $connected_meta );
174
+ foreach ( $meta_clauses as $key => $value ) {
175
+ $clauses[ $key ] .= $value;
176
  }
177
  }
178
 
179
+ return $clauses;
180
  }
181
  }
182
 
lang/posts-to-posts-es_ES.mo ADDED
Binary file
lang/posts-to-posts-es_ES.po ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of the WordPress plugin Posts 2 Posts 0.3 by scribu.
2
+ # Copyright (C) 2010 scribu
3
+ # This file is distributed under the same license as the Posts 2 Posts package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: Posts 2 Posts 0.4\n"
9
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/posts-to-posts\n"
10
+ "POT-Creation-Date: 2010-10-11 13:40+0300\n"
11
+ "PO-Revision-Date: 2010-10-18 22:03-0500\n"
12
+ "Last-Translator: \n"
13
+ "Language-Team: wikichaves.com <info@wikichaves.com>\n"
14
+ "Language: \n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=UTF-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "X-Poedit-Language: Spanish\n"
19
+ "X-Poedit-Country: ARGENTINA\n"
20
+ "X-Poedit-Basepath: ..\n"
21
+
22
+ #: scb/AdminPage.php:164
23
+ msgid "Settings <strong>saved</strong>."
24
+ msgstr "Preferencias <strong>guardado</strong>."
25
+
26
+ #: scb/AdminPage.php:176
27
+ #: scb/AdminPage.php:186
28
+ msgid "Save Changes"
29
+ msgstr "Guardar Cambios"
30
+
31
+ #: scb/AdminPage.php:368
32
+ msgid "Settings"
33
+ msgstr "Preferencias"
34
+
35
+ #: ui/boxes.php:59
36
+ msgid "No connections."
37
+ msgstr "Sin conexiones."
38
+
39
+ #: ui/boxes.php:71
40
+ msgid "Search"
41
+ msgstr "Buscar"
42
+
43
+ #: ui/boxes.php:79
44
+ msgid "Start typing the title of a post you want to connect and then click on to connect it."
45
+ msgstr "Comenzar a escribir el título de la entrada a la que se quiera conectar y luego clickear para conectarla."
46
+
47
+ #: ui/boxes.php:89
48
+ msgid "Enter IDs of posts to connect, separated by commas."
49
+ msgstr "Ingresar los IDs de las entradas a conectar, separadas por comas."
50
+
51
+ #. Plugin Name of the plugin/theme
52
+ msgid "Posts 2 Posts"
53
+ msgstr ""
54
+
55
+ #. Plugin URI of the plugin/theme
56
+ msgid "http://scribu.net/wordpress/posts-to-posts"
57
+ msgstr ""
58
+
59
+ #. Description of the plugin/theme
60
+ msgid "Create many-to-many relationships between all types of posts"
61
+ msgstr ""
62
+
63
+ #. Author of the plugin/theme
64
+ msgid "scribu"
65
+ msgstr ""
66
+
67
+ #. Author URI of the plugin/theme
68
+ msgid "http://scribu.net/"
69
+ msgstr ""
70
+
71
+ #~ msgid "Connected"
72
+ #~ msgstr "Conectat"
lang/posts-to-posts-ro_RO.mo ADDED
Binary file
lang/posts-to-posts-ro_RO.po ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of the WordPress plugin Posts 2 Posts 0.3 by scribu.
2
+ # Copyright (C) 2010 scribu
3
+ # This file is distributed under the same license as the Posts 2 Posts package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: Posts 2 Posts 0.3\n"
9
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/posts-to-posts\n"
10
+ "POT-Creation-Date: 2010-10-11 13:40+0300\n"
11
+ "PO-Revision-Date: 2010-10-11 13:42+0200\n"
12
+ "Last-Translator: scribu <scribu@gmail.com>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+ "Language: \n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=UTF-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+
19
+ #: scb/AdminPage.php:164
20
+ msgid "Settings <strong>saved</strong>."
21
+ msgstr "Setări <strong>salvate</strong>."
22
+
23
+ #: scb/AdminPage.php:176
24
+ #: scb/AdminPage.php:186
25
+ msgid "Save Changes"
26
+ msgstr "Salvează schimbările"
27
+
28
+ #: scb/AdminPage.php:368
29
+ msgid "Settings"
30
+ msgstr "Setări"
31
+
32
+ #: ui/boxes.php:59
33
+ msgid "No connections."
34
+ msgstr "Nu există conexiuni."
35
+
36
+ #: ui/boxes.php:71
37
+ msgid "Search"
38
+ msgstr "Căutare"
39
+
40
+ #: ui/boxes.php:79
41
+ msgid "Start typing the title of a post you want to connect and then click on to connect it."
42
+ msgstr "Începe să scrii titlul post-ului de conectat și apoi fă click pentru a-l conecta."
43
+
44
+ #: ui/boxes.php:89
45
+ msgid "Enter IDs of posts to connect, separated by commas."
46
+ msgstr "Intrdu ID-uri ale post-urilor de conectat, separate prin virgulă."
47
+
48
+ #. Plugin Name of the plugin/theme
49
+ msgid "Posts 2 Posts"
50
+ msgstr ""
51
+
52
+ #. Plugin URI of the plugin/theme
53
+ msgid "http://scribu.net/wordpress/posts-to-posts"
54
+ msgstr ""
55
+
56
+ #. Description of the plugin/theme
57
+ msgid "Create many-to-many relationships between all types of posts"
58
+ msgstr ""
59
+
60
+ #. Author of the plugin/theme
61
+ msgid "scribu"
62
+ msgstr ""
63
+
64
+ #. Author URI of the plugin/theme
65
+ msgid "http://scribu.net/"
66
+ msgstr ""
67
+
68
+ #~ msgid "Connected"
69
+ #~ msgstr "Conectat"
70
+
lang/posts-to-posts.pot CHANGED
@@ -1,4 +1,4 @@
1
- # Translation of the WordPress plugin Posts 2 Posts 0.3 by scribu.
2
  # Copyright (C) 2010 scribu
3
  # This file is distributed under the same license as the Posts 2 Posts package.
4
  # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
@@ -6,49 +6,45 @@
6
  #, fuzzy
7
  msgid ""
8
  msgstr ""
9
- "Project-Id-Version: Posts 2 Posts 0.3\n"
10
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/posts-to-posts\n"
11
- "POT-Creation-Date: 2010-08-04 20:39+0300\n"
12
  "PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
 
15
  "MIME-Version: 1.0\n"
16
  "Content-Type: text/plain; charset=utf-8\n"
17
  "Content-Transfer-Encoding: 8bit\n"
18
 
19
- #: admin/admin.php:94
20
- msgid "Connected"
21
- msgstr ""
22
-
23
- #: admin/admin.php:115
24
- msgid "No connections."
25
  msgstr ""
26
 
27
- #: admin/admin.php:134
28
- msgid "Search"
29
  msgstr ""
30
 
31
- #: admin/admin.php:142
32
- msgid ""
33
- "Start typing name of connected post type and click on it if you want to "
34
- "connect it."
35
  msgstr ""
36
 
37
- #: admin/admin.php:152
38
- msgid ""
39
- "Enter IDs of connected post types separated by commas, or turn on JavaScript!"
40
  msgstr ""
41
 
42
- #: scb/AdminPage.php:167
43
- msgid "Settings <strong>saved</strong>."
44
  msgstr ""
45
 
46
- #: scb/AdminPage.php:179 scb/AdminPage.php:189
47
- msgid "Save Changes"
 
 
48
  msgstr ""
49
 
50
- #: scb/AdminPage.php:371
51
- msgid "Settings"
52
  msgstr ""
53
 
54
  #. Plugin Name of the plugin/theme
@@ -60,7 +56,7 @@ msgid "http://scribu.net/wordpress/posts-to-posts"
60
  msgstr ""
61
 
62
  #. Description of the plugin/theme
63
- msgid "Create connections between posts of different types"
64
  msgstr ""
65
 
66
  #. Author of the plugin/theme
1
+ # Translation of the WordPress plugin Posts 2 Posts 0.4 by scribu.
2
  # Copyright (C) 2010 scribu
3
  # This file is distributed under the same license as the Posts 2 Posts package.
4
  # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
6
  #, fuzzy
7
  msgid ""
8
  msgstr ""
9
+ "Project-Id-Version: Posts 2 Posts 0.4\n"
10
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/posts-to-posts\n"
11
+ "POT-Creation-Date: 2010-10-11 13:40+0300\n"
12
  "PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "Language: \n"
16
  "MIME-Version: 1.0\n"
17
  "Content-Type: text/plain; charset=utf-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
 
20
+ #: scb/AdminPage.php:164
21
+ msgid "Settings <strong>saved</strong>."
 
 
 
 
22
  msgstr ""
23
 
24
+ #: scb/AdminPage.php:176 scb/AdminPage.php:186
25
+ msgid "Save Changes"
26
  msgstr ""
27
 
28
+ #: scb/AdminPage.php:368
29
+ msgid "Settings"
 
 
30
  msgstr ""
31
 
32
+ #: ui/boxes.php:59
33
+ msgid "No connections."
 
34
  msgstr ""
35
 
36
+ #: ui/boxes.php:71
37
+ msgid "Search"
38
  msgstr ""
39
 
40
+ #: ui/boxes.php:79
41
+ msgid ""
42
+ "Start typing the title of a post you want to connect and then click on to "
43
+ "connect it."
44
  msgstr ""
45
 
46
+ #: ui/boxes.php:89
47
+ msgid "Enter IDs of posts to connect, separated by commas."
48
  msgstr ""
49
 
50
  #. Plugin Name of the plugin/theme
56
  msgstr ""
57
 
58
  #. Description of the plugin/theme
59
+ msgid "Create many-to-many relationships between all types of posts"
60
  msgstr ""
61
 
62
  #. Author of the plugin/theme
posts-to-posts.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
  /*
3
  Plugin Name: Posts 2 Posts
4
- Version: 0.4
5
  Plugin Author: scribu
6
- Description: Create connections between posts of different types
7
  Author URI: http://scribu.net/
8
  Plugin URI: http://scribu.net/wordpress/posts-to-posts
9
  Text Domain: posts-to-posts
@@ -29,6 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29
  require dirname( __FILE__ ) . '/scb/load.php';
30
 
31
  function _p2p_init() {
 
 
32
  require dirname( __FILE__ ) . '/storage.php';
33
  require dirname( __FILE__ ) . '/api.php';
34
  require dirname( __FILE__ ) . '/ui/ui.php';
1
  <?php
2
  /*
3
  Plugin Name: Posts 2 Posts
4
+ Version: 0.5.1
5
  Plugin Author: scribu
6
+ Description: Create many-to-many relationships between all types of posts
7
  Author URI: http://scribu.net/
8
  Plugin URI: http://scribu.net/wordpress/posts-to-posts
9
  Text Domain: posts-to-posts
29
  require dirname( __FILE__ ) . '/scb/load.php';
30
 
31
  function _p2p_init() {
32
+ load_plugin_textdomain( 'posts-to-posts', '', dirname( plugin_basename( __FILE__ ) ) . '/lang' );
33
+
34
  require dirname( __FILE__ ) . '/storage.php';
35
  require dirname( __FILE__ ) . '/api.php';
36
  require dirname( __FILE__ ) . '/ui/ui.php';
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: scribu
3
  Donate link: http://scribu.net/paypal
4
  Tags: cms, custom post types, relationships, many-to-many
5
  Requires at least: 3.0
6
- Tested up to: 3.0
7
- Stable tag: 0.4
8
 
9
  Create connections between posts
10
 
@@ -49,6 +49,18 @@ Make sure your host is running PHP 5. The only foolproof way to do this is to ad
49
 
50
  == Changelog ==
51
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  = 0.4 =
53
  * introduced 'connected_from', 'connected_to', 'connected' vars to WP_Query
54
  * replaced $reciprocal with $data as the third argument
3
  Donate link: http://scribu.net/paypal
4
  Tags: cms, custom post types, relationships, many-to-many
5
  Requires at least: 3.0
6
+ Tested up to: 3.1-alpha
7
+ Stable tag: 0.5.1
8
 
9
  Create connections between posts
10
 
49
 
50
  == Changelog ==
51
 
52
+ = 0.5.1 =
53
+ * fixed fatal error on Menus screen
54
+
55
+ = 0.5 =
56
+ * added 'connected_meta' var to WP_Query
57
+ * attach p2p_id to each post found via WP_Query
58
+ * 'connected_to' => 'any' etc.
59
+ * $data parameter can also be a meta_query
60
+ * metabox bugfixes
61
+ * fixed l10n loading
62
+ * [more info](http://scribu.net/wordpress/posts-to-posts/p2p-0-5.html)
63
+
64
  = 0.4 =
65
  * introduced 'connected_from', 'connected_to', 'connected' vars to WP_Query
66
  * replaced $reciprocal with $data as the third argument
scb/Cron.php CHANGED
@@ -16,18 +16,43 @@ class scbCron {
16
  string $action OR callback $callback
17
  string $schedule OR number $interval
18
  array $callback_args ( optional )
19
- * @param bool Debug mode
20
  */
21
- function __construct( $file, $args, $debug = false ) {
22
- $this->_set_args( $args );
23
 
24
- scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
25
- register_deactivation_hook( $file, array( $this, 'unschedule' ) );
 
26
 
27
- add_filter( 'cron_schedules', array( $this, '_add_timing' ) );
 
 
 
 
 
28
 
29
- if ( $debug )
30
- self::debug();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
33
  /* Change the interval of the cron job
@@ -69,24 +94,26 @@ class scbCron {
69
 
70
  /**
71
  * Execute the job now
 
72
  */
73
- function do_now() {
74
- do_action( $this->hook );
 
 
 
75
  }
76
 
77
  /**
78
  * Execute the job with a given delay
79
- * @param int Delay in seconds
 
80
  */
81
- function do_once( $delay = 0 ) {
82
- wp_schedule_single_event( time() + $delay, $this->hook, $this->callback_args );
83
- }
84
 
85
- /**
86
- * Display current cron jobs
87
- */
88
- function debug() {
89
- add_action( 'admin_footer', array( __CLASS__, '_debug' ) );
90
  }
91
 
92
 
@@ -103,15 +130,6 @@ class scbCron {
103
  return $schedules;
104
  }
105
 
106
- function _debug() {
107
- if ( ! current_user_can( 'manage_options' ) )
108
- return;
109
-
110
- echo "<pre>";
111
- print_r( get_option( 'cron' ) );
112
- echo "</pre>";
113
- }
114
-
115
  protected function schedule() {
116
  if ( ! $this->time )
117
  $this->time = time();
@@ -119,38 +137,6 @@ class scbCron {
119
  wp_schedule_event( $this->time, $this->schedule, $this->hook, $this->callback_args );
120
  }
121
 
122
- protected function _set_args( $args ) {
123
- extract( $args );
124
-
125
- // Set hook
126
- if ( isset( $action ) ) {
127
- $this->hook = $action;
128
- } elseif ( isset( $callback ) ) {
129
- $this->hook = self::_callback_to_string( $callback );
130
-
131
- add_action( $this->hook, $callback );
132
- } elseif ( method_exists( $this, 'callback' ) ) {
133
- $this->hook = self::_callback_to_string( $callback );
134
-
135
- add_action( $this->hook, $callback );
136
- } else {
137
- trigger_error( '$action OR $callback not set', E_USER_WARNING );
138
- }
139
-
140
- // Set schedule
141
- if ( isset( $interval ) ) {
142
- $this->schedule = $interval . 'secs';
143
- $this->interval = $interval;
144
- } elseif ( isset( $schedule ) ) {
145
- $this->schedule = $schedule;
146
- } else {
147
- trigger_error( '$schedule OR $interval not set', E_USER_WARNING );
148
- }
149
-
150
- if ( isset( $callback_args ) )
151
- $this->callback_args = ( array ) $callback_args;
152
- }
153
-
154
  protected static function really_clear_scheduled_hook( $name ) {
155
  $crons = _get_cron_array();
156
 
16
  string $action OR callback $callback
17
  string $schedule OR number $interval
18
  array $callback_args ( optional )
 
19
  */
20
+ function __construct( $file, $args ) {
21
+ extract( $args, EXTR_SKIP );
22
 
23
+ // Set time & schedule
24
+ if ( isset( $time ) )
25
+ $this->time = $time;
26
 
27
+ if ( isset( $interval ) ) {
28
+ $this->schedule = $interval . 'secs';
29
+ $this->interval = $interval;
30
+ } elseif ( isset( $schedule ) ) {
31
+ $this->schedule = $schedule;
32
+ }
33
 
34
+ // Set hook
35
+ if ( isset( $action ) ) {
36
+ $this->hook = $action;
37
+ } elseif ( isset( $callback ) ) {
38
+ $this->hook = self::_callback_to_string( $callback );
39
+ add_action( $this->hook, $callback );
40
+ } elseif ( method_exists( $this, 'callback' ) ) {
41
+ $this->hook = self::_callback_to_string( array( $this, 'callback' ) );
42
+ add_action( $this->hook, $callback );
43
+ } else {
44
+ trigger_error( '$action OR $callback not set', E_USER_WARNING );
45
+ }
46
+
47
+ if ( isset( $callback_args ) )
48
+ $this->callback_args = ( array ) $callback_args;
49
+
50
+ if ( $this->schedule ) {
51
+ scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
52
+ register_deactivation_hook( $file, array( $this, 'unschedule' ) );
53
+ }
54
+
55
+ add_filter( 'cron_schedules', array( $this, '_add_timing' ) );
56
  }
57
 
58
  /* Change the interval of the cron job
94
 
95
  /**
96
  * Execute the job now
97
+ * @param array $args List of arguments to pass to the callback
98
  */
99
+ function do_now( $args = null ) {
100
+ if ( is_null( $args ) )
101
+ $args = $this->callback_args;
102
+
103
+ do_action_ref_array( $this->hook, $args );
104
  }
105
 
106
  /**
107
  * Execute the job with a given delay
108
+ * @param int $delay in seconds
109
+ * @param array $args List of arguments to pass to the callback
110
  */
111
+ function do_once( $delay = 0, $args = null ) {
112
+ if ( is_null( $args ) )
113
+ $args = $this->callback_args;
114
 
115
+ wp_clear_scheduled_hook( $this->hook, $args );
116
+ wp_schedule_single_event( time() + $delay, $this->hook, $args );
 
 
 
117
  }
118
 
119
 
130
  return $schedules;
131
  }
132
 
 
 
 
 
 
 
 
 
 
133
  protected function schedule() {
134
  if ( ! $this->time )
135
  $this->time = time();
137
  wp_schedule_event( $this->time, $this->schedule, $this->hook, $this->callback_args );
138
  }
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  protected static function really_clear_scheduled_hook( $name ) {
141
  $crons = _get_cron_array();
142
 
scb/Forms.php CHANGED
@@ -213,9 +213,14 @@ class scbForms {
213
  // Find relevant formdata
214
  $match = NULL;
215
  if ( $checked === NULL ) {
216
- $match = @self::$formdata[str_replace( '[]', '', $$i1 )];
217
- if ( is_array( $match ) ) {
218
- $match = $match[$i];
 
 
 
 
 
219
  }
220
  } else if ( is_array( $checked ) ) {
221
  $cur_args['checked'] = isset( $checked[$i] ) && $checked[$i];
@@ -378,6 +383,8 @@ class scbForms {
378
  }
379
 
380
  private static function array_to_attr( $attr ) {
 
 
381
  $out = '';
382
  foreach ( $attr as $key => $value )
383
  $out .= ' ' . $key . '=' . '"' . esc_attr( $value ) . '"';
213
  // Find relevant formdata
214
  $match = NULL;
215
  if ( $checked === NULL ) {
216
+ $key = str_replace( '[]', '', $$i1 );
217
+
218
+ if ( isset( self::$formdata[ $key ] ) ) {
219
+ $match = self::$formdata[ $key ];
220
+
221
+ if ( is_array( $match ) ) {
222
+ $match = $match[$i];
223
+ }
224
  }
225
  } else if ( is_array( $checked ) ) {
226
  $cur_args['checked'] = isset( $checked[$i] ) && $checked[$i];
383
  }
384
 
385
  private static function array_to_attr( $attr ) {
386
+ $attr = array_filter( (array) $attr );
387
+
388
  $out = '';
389
  foreach ( $attr as $key => $value )
390
  $out .= ' ' . $key . '=' . '"' . esc_attr( $value ) . '"';
scb/QueryManipulation.php CHANGED
@@ -16,14 +16,21 @@ class scbQueryManipulation {
16
  );
17
 
18
  public function __construct( $callback, $once = true ) {
 
 
 
 
 
 
 
 
 
19
  $this->callback = $callback;
20
 
21
  $this->enable();
22
 
23
- if ( !$once )
24
- return;
25
-
26
- add_filter( 'posts_request', array( $this, '_disable' ) );
27
  }
28
 
29
  function _disable( $request ) {
@@ -66,6 +73,11 @@ class scbQueryManipulation {
66
  }
67
 
68
  function alter( $query ) {
 
 
 
 
 
69
  $this->bits = call_user_func( $this->callback, $this->bits, $this->wp_query );
70
  }
71
 
16
  );
17
 
18
  public function __construct( $callback, $once = true ) {
19
+ global $wp_version;
20
+
21
+ if ( version_compare( $wp_version, '3.1-alpha', '>=' ) ) {
22
+ if ( !$once ) {
23
+ add_filter( 'posts_clauses', $callback, 10, 2 );
24
+ return;
25
+ }
26
+ }
27
+
28
  $this->callback = $callback;
29
 
30
  $this->enable();
31
 
32
+ if ( $once )
33
+ add_filter( 'posts_request', array( $this, '_disable' ) );
 
 
34
  }
35
 
36
  function _disable( $request ) {
73
  }
74
 
75
  function alter( $query ) {
76
+ // suppress_filters => true
77
+ if ( is_null( $this->wp_query ) ) {
78
+ return;
79
+ }
80
+
81
  $this->bits = call_user_func( $this->callback, $this->bits, $this->wp_query );
82
  }
83
 
scb/Table.php CHANGED
@@ -9,10 +9,13 @@ class scbTable {
9
  function __construct( $name, $file, $columns, $upgrade_method = 'dbDelta' ) {
10
  global $wpdb;
11
 
12
- $this->name = $wpdb->$name = $wpdb->prefix . $name;
13
  $this->columns = $columns;
14
  $this->upgrade_method = $upgrade_method;
15
 
 
 
 
16
  scbUtil::add_activation_hook( $file, array( $this, 'install' ) );
17
  scbUtil::add_uninstall_hook( $file, array( $this, 'uninstall' ) );
18
  }
9
  function __construct( $name, $file, $columns, $upgrade_method = 'dbDelta' ) {
10
  global $wpdb;
11
 
12
+ $this->name = $wpdb->prefix . $name;
13
  $this->columns = $columns;
14
  $this->upgrade_method = $upgrade_method;
15
 
16
+ $wpdb->tables[] = $name;
17
+ $wpdb->$name = $this->name;
18
+
19
  scbUtil::add_activation_hook( $file, array( $this, 'install' ) );
20
  scbUtil::add_uninstall_hook( $file, array( $this, 'uninstall' ) );
21
  }
scb/Util.php CHANGED
@@ -115,19 +115,36 @@ class scbUtil {
115
 
116
  //_____Minimalist HTML framework_____
117
 
118
-
 
 
 
 
 
 
 
119
  if ( ! function_exists( 'html' ) ):
120
- function html( $tag, $attributes = array(), $content = '' ) {
121
- if ( is_array( $attributes ) ) {
 
 
 
 
122
  $closing = $tag;
 
123
  foreach ( $attributes as $key => $value ) {
124
- $tag .= ' ' . $key . '="' . esc_attr( $value ) . '"';
125
  }
126
  } else {
127
- $content = $attributes;
128
- list( $closing ) = explode(' ', $tag, 2);
129
  }
130
 
 
 
 
 
 
 
131
  return "<{$tag}>{$content}</{$closing}>";
132
  }
133
  endif;
115
 
116
  //_____Minimalist HTML framework_____
117
 
118
+ /*
119
+ * Examples:
120
+ *
121
+ * html( 'p', 'Hello world!' ); <p>Hello world!</p>
122
+ * html( 'a', array( 'href' => 'http://example.com' ), 'A link' ); <a href="http://example.com">A link</a>
123
+ * html( 'img', array( 'src' => 'http://example.com/f.jpg' ) ); <img src="http://example.com/f.jpg" />
124
+ * html( 'ul', html( 'li', 'a' ), html( 'li', 'b' ) ); <ul><li>a</li><li>b</li></ul>
125
+ */
126
  if ( ! function_exists( 'html' ) ):
127
+ function html( $tag ) {
128
+ $args = func_get_args();
129
+
130
+ $tag = array_shift( $args );
131
+
132
+ if ( is_array( $args[0] ) ) {
133
  $closing = $tag;
134
+ $attributes = array_shift( $args );
135
  foreach ( $attributes as $key => $value ) {
136
+ $tag .= ' ' . $key . '="' . htmlspecialchars( $value, ENT_QUOTES ) . '"';
137
  }
138
  } else {
139
+ list( $closing ) = explode( ' ', $tag, 2 );
 
140
  }
141
 
142
+ if ( in_array( $closing, array( 'area', 'base', 'basefont', 'br', 'hr', 'input', 'img', 'link', 'meta' ) ) ) {
143
+ return "<{$tag} />";
144
+ }
145
+
146
+ $content = implode( '', $args );
147
+
148
  return "<{$tag}>{$content}</{$closing}>";
149
  }
150
  endif;
scb/load.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- $GLOBALS['_scb_data'] = array( 25, __FILE__, array(
4
  'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
  'scbWidget', 'scbAdminPage', 'scbBoxesPage',
6
  'scbQueryManipulation', 'scbCron',
@@ -12,7 +12,7 @@ class scbLoad4 {
12
  private static $candidates;
13
  private static $classes;
14
  private static $callbacks = array();
15
-
16
  private static $loaded;
17
 
18
  static function init( $callback = '' ) {
@@ -28,7 +28,7 @@ class scbLoad4 {
28
  }
29
 
30
  // TODO: don't load when activating a plugin ?
31
- add_action( 'plugins_loaded', array( __CLASS__, 'load' ), 10, 0 );
32
  }
33
 
34
  static function delayed_activation( $plugin ) {
@@ -37,13 +37,14 @@ class scbLoad4 {
37
  if ( '.' == $plugin_dir )
38
  return;
39
 
40
- foreach ( self::$callbacks as $file => $callback )
41
- if ( plugin_basename( dirname( dirname( $file ) ) ) == $plugin_dir ) {
42
  self::load( false );
43
  call_user_func( $callback );
44
  do_action( 'scb_activation_' . $plugin );
45
  break;
46
  }
 
47
  }
48
 
49
  static function load( $do_callbacks = true ) {
1
  <?php
2
 
3
+ $GLOBALS['_scb_data'] = array( 30, __FILE__, array(
4
  'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
  'scbWidget', 'scbAdminPage', 'scbBoxesPage',
6
  'scbQueryManipulation', 'scbCron',
12
  private static $candidates;
13
  private static $classes;
14
  private static $callbacks = array();
15
+
16
  private static $loaded;
17
 
18
  static function init( $callback = '' ) {
28
  }
29
 
30
  // TODO: don't load when activating a plugin ?
31
+ add_action( 'plugins_loaded', array( __CLASS__, 'load' ), 9, 0 );
32
  }
33
 
34
  static function delayed_activation( $plugin ) {
37
  if ( '.' == $plugin_dir )
38
  return;
39
 
40
+ foreach ( self::$callbacks as $file => $callback ) {
41
+ if ( dirname( dirname( plugin_basename( $file ) ) ) == $plugin_dir ) {
42
  self::load( false );
43
  call_user_func( $callback );
44
  do_action( 'scb_activation_' . $plugin );
45
  break;
46
  }
47
+ }
48
  }
49
 
50
  static function load( $do_callbacks = true ) {
storage.php CHANGED
@@ -47,16 +47,17 @@ class P2P_Connections {
47
  function get( $from, $to, $data = array(), $_return_p2p_ids = false ) {
48
  global $wpdb;
49
 
50
- $select = "p2p_id";
51
- $where = "";
 
52
 
53
  switch ( $to ) {
54
  case 'from':
55
- $select .= $_return_p2p_ids ? '' : ', p2p_to AS post_id';
56
  $where .= $wpdb->prepare( "p2p_from = %d", $from );
57
  break;
58
  case 'to':
59
- $select .= $_return_p2p_ids ? '' : ', p2p_from AS post_id';
60
  $where .= $wpdb->prepare( "p2p_to = %d", $from );
61
  break;
62
  default:
@@ -65,22 +66,12 @@ class P2P_Connections {
65
  }
66
 
67
  if ( !empty( $data ) ) {
68
- $clauses = array();
69
- foreach ( $data as $key => $value ) {
70
- $clauses[] = $wpdb->prepare( "WHEN %s THEN meta_value = %s ", $key, $value );
71
- }
72
-
73
- $where .= " AND p2p_id IN (
74
- SELECT p2p_id
75
- FROM $wpdb->p2pmeta
76
- WHERE CASE meta_key
77
- " . implode( "\n", $clauses ) . "
78
- END
79
- GROUP BY p2p_id HAVING COUNT(p2p_id) = " . count($data) . "
80
- )";
81
  }
82
 
83
- $query = "SELECT $select FROM $wpdb->p2p WHERE $where";
84
 
85
  if ( $_return_p2p_ids )
86
  return $wpdb->get_col( $query );
@@ -181,3 +172,93 @@ function p2p_delete_meta($p2p_id, $meta_key, $meta_value = '') {
181
  return delete_metadata('p2p', $p2p_id, $meta_key, $meta_value);
182
  }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  function get( $from, $to, $data = array(), $_return_p2p_ids = false ) {
48
  global $wpdb;
49
 
50
+ $fields = "$wpdb->p2p.p2p_id";
51
+ $where = '';
52
+ $join = '';
53
 
54
  switch ( $to ) {
55
  case 'from':
56
+ $fields .= $_return_p2p_ids ? '' : ', p2p_to AS post_id';
57
  $where .= $wpdb->prepare( "p2p_from = %d", $from );
58
  break;
59
  case 'to':
60
+ $fields .= $_return_p2p_ids ? '' : ', p2p_from AS post_id';
61
  $where .= $wpdb->prepare( "p2p_to = %d", $from );
62
  break;
63
  default:
66
  }
67
 
68
  if ( !empty( $data ) ) {
69
+ $clauses = _p2p_meta_sql_helper( $data );
70
+ $join .= $clauses['join'];
71
+ $where .= $clauses['where'];
 
 
 
 
 
 
 
 
 
 
72
  }
73
 
74
+ $query = "SELECT $fields FROM $wpdb->p2p $join WHERE $where";
75
 
76
  if ( $_return_p2p_ids )
77
  return $wpdb->get_col( $query );
172
  return delete_metadata('p2p', $p2p_id, $meta_key, $meta_value);
173
  }
174
 
175
+ function _p2p_meta_sql_helper( $data ) {
176
+ global $wpdb;
177
+
178
+ if ( isset( $data[0] ) ) {
179
+ $meta_query = $data;
180
+ }
181
+ else {
182
+ $meta_query = array();
183
+
184
+ foreach ( $data as $key => $value ) {
185
+ $meta_query[] = compact( 'key', 'value' );
186
+ }
187
+ }
188
+
189
+ return p2p_get_meta_sql( $meta_query, 'p2p', $wpdb->p2p, 'p2p_id' );
190
+ }
191
+
192
+ // WP < 3.1-alpha
193
+ function p2p_get_meta_sql( $meta_query, $meta_type, $primary_table, $primary_id_column ) {
194
+ global $wpdb;
195
+
196
+ if ( ! $meta_table = _get_meta_table( $meta_type ) )
197
+ return false;
198
+
199
+ $meta_id_column = esc_sql( $meta_type . '_id' );
200
+
201
+ $clauses = array();
202
+
203
+ $join = '';
204
+ $where = '';
205
+ $i = 0;
206
+ foreach ( $meta_query as $q ) {
207
+ $meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : '';
208
+ $meta_value = isset( $q['value'] ) ? $q['value'] : '';
209
+ $meta_compare = isset( $q['compare'] ) ? strtoupper( $q['compare'] ) : '=';
210
+ $meta_type = isset( $q['type'] ) ? strtoupper( $q['type'] ) : 'CHAR';
211
+
212
+ if ( ! in_array( $meta_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) )
213
+ $meta_compare = '=';
214
+
215
+ if ( 'NUMERIC' == $meta_type )
216
+ $meta_type = 'SIGNED';
217
+ elseif ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) )
218
+ $meta_type = 'CHAR';
219
+
220
+ if ( empty( $meta_key ) && empty( $meta_value ) )
221
+ continue;
222
+
223
+ $alias = $i ? 'mt' . $i : $meta_table;
224
+
225
+ $join .= "\nINNER JOIN $meta_table";
226
+ $join .= $i ? " AS $alias" : '';
227
+ $join .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)";
228
+
229
+ $i++;
230
+
231
+ if ( !empty( $meta_key ) )
232
+ $where .= $wpdb->prepare( " AND $alias.meta_key = %s", $meta_key );
233
+
234
+ if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
235
+ if ( ! is_array( $meta_value ) )
236
+ $meta_value = preg_split( '/[,\s]+/', $meta_value );
237
+ } else {
238
+ $meta_value = trim( $meta_value );
239
+ }
240
+
241
+ if ( empty( $meta_value ) )
242
+ continue;
243
+
244
+ if ( 'IN' == substr( $meta_compare, -2) ) {
245
+ $meta_field_types = substr( str_repeat( ',%s', count( $meta_value ) ), 1 );
246
+ $meta_compare_string = "($meta_field_types)";
247
+ unset( $meta_field_types );
248
+ } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) {
249
+ $meta_value = array_slice( $meta_value, 0, 2 );
250
+ $meta_compare_string = '%s AND %s';
251
+ } elseif ( 'LIKE' == substr( $meta_compare, -4 ) ) {
252
+ $meta_value = '%' . like_escape( $meta_value ) . '%';
253
+ $meta_compare_string = '%s';
254
+ } else {
255
+ $meta_compare_string = '%s';
256
+ }
257
+ $where .= $wpdb->prepare( " AND CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string}", $meta_value );
258
+
259
+ unset( $meta_compare_string );
260
+ }
261
+
262
+ return compact( 'join', 'where' );
263
+ }
264
+
ui/admin.js DELETED
@@ -1,79 +0,0 @@
1
- jQuery(document).ready(function($) {
2
- var update_input = function($metabox) {
3
- $metabox.find('.p2p_connected .howto').remove();
4
-
5
- var ids = [];
6
- $metabox.find('.p2p_connected input:checked').each(function() {
7
- ids.push($(this).val());
8
- });
9
- $metabox.find('.p2p_connected_ids').val(ids.join(','));
10
- };
11
-
12
- $('.p2p_connected').delegate('input', 'change', function() {
13
- update_input($(this).parents('.p2p_metabox'));
14
- });
15
-
16
- $('.p2p_results').delegate('a', 'click', function() {
17
- var $self = $(this);
18
- $metabox = $self.parents('.p2p_metabox'),
19
- $list = $metabox.find('.p2p_connected');
20
-
21
- if ( !$list.find('input[value=' + $self.attr('name') + ']').length ) {
22
- $list
23
- .append($('<li>')
24
- .append($('<input>').attr({
25
- 'type': 'checkbox',
26
- 'checked': 'checked',
27
- 'id': 'p2p_checkbox_' + $self.attr('name'),
28
- 'value': $self.attr('name'),
29
- 'autocomplete': 'off'
30
- }))
31
- .append($('<label>').attr({
32
- 'for': 'p2p_checkbox_' + $self.attr('name')
33
- }).html($self.html()))
34
- );
35
- }
36
-
37
- update_input($metabox);
38
-
39
- return false;
40
- });
41
-
42
- var delayed = undefined;
43
-
44
- $('.p2p_search :text').keyup(function() {
45
-
46
- if ( delayed != undefined )
47
- clearTimeout(delayed);
48
-
49
- var $self = $(this);
50
- $metabox = $self.parents('.p2p_metabox'),
51
- $results = $metabox.find('.p2p_results'),
52
- post_type = $self.attr('name').replace('p2p_search_', ''),
53
- old_value = '',
54
- $spinner = $metabox.find('.waiting');
55
-
56
- var delayed = setTimeout(function() {
57
- if ( !$self.val().length ) {
58
- $results.html('');
59
- return;
60
- }
61
-
62
- if ( $self.val() == old_value )
63
- return;
64
- old_value = $self.val();
65
-
66
- $spinner.show();
67
- $.getJSON(ajaxurl, {action: 'p2p_search', q: $self.val(), post_type: post_type}, function(data) {
68
- $spinner.hide();
69
-
70
- $results.html('');
71
-
72
- $.each(data, function(id, title) {
73
- $results.append('<li><a href="#" name="' + id + '">' + title + '</a></li>');
74
- });
75
- });
76
- }, 400);
77
- });
78
- });
79
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui/boxes.php CHANGED
@@ -7,8 +7,6 @@ class P2P_Box_Multiple extends P2P_Box {
7
  function init() {
8
  add_action( 'admin_print_styles-post.php', array( __CLASS__, 'scripts' ) );
9
  add_action( 'admin_print_styles-post-new.php', array( __CLASS__, 'scripts' ) );
10
-
11
- add_action( 'wp_ajax_p2p_search', array( __CLASS__, 'ajax_search' ) );
12
  }
13
 
14
  function scripts() {
@@ -52,7 +50,7 @@ class P2P_Box_Multiple extends P2P_Box {
52
  <input type="hidden" name="<?php echo $this->input_name( array( 'all', '' ) ); ?>" value="<?php echo $p2p_id; ?>">
53
  <?php } ?>
54
 
55
- <div class="p2p_metabox">
56
  <div class="hide-if-no-js checkboxes">
57
  <ul class="p2p_connected">
58
  <?php if ( empty( $connected_ids ) ) { ?>
@@ -76,7 +74,7 @@ class P2P_Box_Multiple extends P2P_Box {
76
  ); ?>
77
 
78
  <ul class="p2p_results"></ul>
79
- <p class="howto"><?php _e( 'Start typing name of connected post type and click on it if you want to connect it.', 'posts-to-posts' ); ?></p>
80
  </div>
81
 
82
  <div class="hide-if-js">
@@ -134,14 +132,10 @@ class P2P_Box_Multiple extends P2P_Box {
134
  return array_intersect( $connected_posts, $post_ids ); // to preserve p2p_id keys
135
  }
136
 
137
- function ajax_search() {
138
- $post_type_name = $_GET['post_type'];
139
-
140
- add_filter( 'posts_search', array( __CLASS__, 'only_search_by_title' ) );
141
-
142
- $args = array(
143
- 's' => $_GET['q'],
144
- 'post_type' => $post_type_name,
145
  'post_status' => 'any',
146
  'posts_per_page' => 5,
147
  'order' => 'ASC',
@@ -150,22 +144,6 @@ class P2P_Box_Multiple extends P2P_Box {
150
  'update_post_term_cache' => false,
151
  'update_post_meta_cache' => false
152
  );
153
-
154
- $posts = get_posts( $args );
155
-
156
- $results = array();
157
- foreach ( $posts as $post )
158
- $results[ $post->ID ] = $post->post_title;
159
-
160
- die( json_encode( $results ) );
161
- }
162
-
163
- function only_search_by_title( $sql ) {
164
- remove_filter( current_filter(), array( __CLASS__, __FUNCTION__ ) );
165
-
166
- list( $sql ) = explode( ' OR ', $sql, 2 );
167
-
168
- return $sql . '))';
169
  }
170
  }
171
 
7
  function init() {
8
  add_action( 'admin_print_styles-post.php', array( __CLASS__, 'scripts' ) );
9
  add_action( 'admin_print_styles-post-new.php', array( __CLASS__, 'scripts' ) );
 
 
10
  }
11
 
12
  function scripts() {
50
  <input type="hidden" name="<?php echo $this->input_name( array( 'all', '' ) ); ?>" value="<?php echo $p2p_id; ?>">
51
  <?php } ?>
52
 
53
+ <div id="p2p-box-<?php echo $this->box_id; ?>" class="p2p_metabox<?php if ( $this->reversed ) echo ' reversed'; ?>">
54
  <div class="hide-if-no-js checkboxes">
55
  <ul class="p2p_connected">
56
  <?php if ( empty( $connected_ids ) ) { ?>
74
  ); ?>
75
 
76
  <ul class="p2p_results"></ul>
77
+ <p class="howto"><?php _e( 'Start typing the title of a post you want to connect and then click on to connect it.', 'posts-to-posts' ); ?></p>
78
  </div>
79
 
80
  <div class="hide-if-js">
132
  return array_intersect( $connected_posts, $post_ids ); // to preserve p2p_id keys
133
  }
134
 
135
+ function get_search_args( $search ) {
136
+ return array(
137
+ 's' => $search,
138
+ 'post_type' => $this->to,
 
 
 
 
139
  'post_status' => 'any',
140
  'posts_per_page' => 5,
141
  'order' => 'ASC',
144
  'update_post_term_cache' => false,
145
  'update_post_meta_cache' => false
146
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
  }
149
 
ui/ui.js CHANGED
@@ -45,7 +45,15 @@ jQuery(document).ready(function($) {
45
  old_value = $self.val();
46
 
47
  $spinner.show();
48
- $.getJSON(ajaxurl, {action: 'p2p_search', q: $self.val(), post_type: post_type}, function(data) {
 
 
 
 
 
 
 
 
49
  $spinner.hide();
50
 
51
  $results.html('');
45
  old_value = $self.val();
46
 
47
  $spinner.show();
48
+
49
+ var data = {
50
+ action: 'p2p_search',
51
+ q: $self.val(),
52
+ box_id: $metabox.attr('id').replace('p2p-box-', ''),
53
+ reversed: +$metabox.hasClass('reversed')
54
+ }
55
+
56
+ $.getJSON(ajaxurl, data, function(data) {
57
  $spinner.hide();
58
 
59
  $results.html('');
ui/ui.php CHANGED
@@ -5,7 +5,7 @@ abstract class P2P_Box {
5
  protected $reversed;
6
  protected $direction;
7
 
8
- private $box_id;
9
  private $input;
10
 
11
  abstract function save( $post_id, $data );
@@ -19,16 +19,17 @@ abstract class P2P_Box {
19
  // Internal stuff
20
 
21
 
22
- public function __construct( $args, $reversed, $box_id ) {
23
  foreach ( $args as $key => $value )
24
  $this->$key = $value;
25
 
26
  $this->box_id = $box_id;
27
- $this->reversed = $reversed;
28
 
29
  $this->input = new p2pInput( array( 'p2p', $box_id ) );
30
 
31
- $this->direction = $this->reversed ? 'to' : 'from';
 
 
32
 
33
  if ( $this->reversed )
34
  list( $this->to, $this->from ) = array( $this->from, $this->to );
@@ -100,7 +101,6 @@ class p2pInput {
100
 
101
  class P2P_Connection_Types {
102
 
103
- private static $ctype_id = 0;
104
  private static $ctypes = array();
105
 
106
  static public function register( $args ) {
@@ -118,6 +118,7 @@ class P2P_Connection_Types {
118
  static function init() {
119
  add_action( 'add_meta_boxes', array( __CLASS__, '_register' ) );
120
  add_action( 'save_post', array( __CLASS__, '_save' ), 10 );
 
121
  }
122
 
123
  static function _register( $from ) {
@@ -136,19 +137,56 @@ class P2P_Connection_Types {
136
  }
137
  }
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  private static function filter_ctypes( $post_type ) {
140
  $r = array();
141
- $i = 0;
142
- foreach ( self::$ctypes as $args ) {
143
- if ( $post_type == $args['from'] ) {
144
- $reversed = false;
 
145
  } elseif ( $args['reciprocal'] && $post_type == $args['to'] ) {
146
- $reversed = true;
 
 
147
  } else {
148
- continue;
149
  }
150
 
151
- $r[] = new $args['box']($args, $reversed, $i++);
 
 
 
152
  }
153
 
154
  return $r;
5
  protected $reversed;
6
  protected $direction;
7
 
8
+ protected $box_id;
9
  private $input;
10
 
11
  abstract function save( $post_id, $data );
19
  // Internal stuff
20
 
21
 
22
+ public function __construct( $args, $direction, $box_id ) {
23
  foreach ( $args as $key => $value )
24
  $this->$key = $value;
25
 
26
  $this->box_id = $box_id;
 
27
 
28
  $this->input = new p2pInput( array( 'p2p', $box_id ) );
29
 
30
+ $this->direction = $direction;
31
+
32
+ $this->reversed = ( 'to' == $direction );
33
 
34
  if ( $this->reversed )
35
  list( $this->to, $this->from ) = array( $this->from, $this->to );
101
 
102
  class P2P_Connection_Types {
103
 
 
104
  private static $ctypes = array();
105
 
106
  static public function register( $args ) {
118
  static function init() {
119
  add_action( 'add_meta_boxes', array( __CLASS__, '_register' ) );
120
  add_action( 'save_post', array( __CLASS__, '_save' ), 10 );
121
+ add_action( 'wp_ajax_p2p_search', array( __CLASS__, 'ajax_search' ) );
122
  }
123
 
124
  static function _register( $from ) {
137
  }
138
  }
139
 
140
+ function ajax_search() {
141
+ add_filter( 'posts_search', array( __CLASS__, '_search_by_title' ) );
142
+
143
+ $box_id = absint( $_GET['box_id'] );
144
+ $reversed = (bool) $_GET['reversed'];
145
+
146
+ if ( !isset( self::$ctypes[ $box_id ] ) )
147
+ die(0);
148
+
149
+ $args = self::$ctypes[ $box_id ];
150
+ $box = new $args['box']($args, $reversed, $box_id);
151
+
152
+ $posts = get_posts( $box->get_search_args( $_GET['q'] ) );
153
+
154
+ $results = array();
155
+ foreach ( $posts as $post ) {
156
+ $GLOBALS['post'] = $post;
157
+ $results[ $post->ID ] = apply_filters( 'the_title', $post->post_title );
158
+ }
159
+
160
+ die( json_encode( $results ) );
161
+ }
162
+
163
+ function _search_by_title( $sql ) {
164
+ remove_filter( current_filter(), array( __CLASS__, __FUNCTION__ ) );
165
+
166
+ list( $sql ) = explode( ' OR ', $sql, 2 );
167
+
168
+ return $sql . '))';
169
+ }
170
+
171
  private static function filter_ctypes( $post_type ) {
172
  $r = array();
173
+ foreach ( self::$ctypes as $box_id => $args ) {
174
+ $direction = false;
175
+
176
+ if ( $args['reciprocal'] && $args['from'] == $args['to'] ) {
177
+ $direction = 'any';
178
  } elseif ( $args['reciprocal'] && $post_type == $args['to'] ) {
179
+ $direction = 'to';
180
+ } elseif ( $post_type == $args['from'] ) {
181
+ $direction = 'from';
182
  } else {
183
+ continue;
184
  }
185
 
186
+ if ( !$direction )
187
+ continue;
188
+
189
+ $r[ $box_id ] = new $args['box']($args, $direction, $box_id);
190
  }
191
 
192
  return $r;