Version Description
- fixed fatal error on Menus screen
Download this release
Release Info
Developer | scribu |
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 +58 -9
- lang/posts-to-posts-es_ES.mo +0 -0
- lang/posts-to-posts-es_ES.po +72 -0
- lang/posts-to-posts-ro_RO.mo +0 -0
- lang/posts-to-posts-ro_RO.po +70 -0
- lang/posts-to-posts.pot +21 -25
- posts-to-posts.php +4 -2
- readme.txt +14 -2
- scb/Cron.php +46 -60
- scb/Forms.php +10 -3
- scb/QueryManipulation.php +16 -4
- scb/Table.php +4 -1
- scb/Util.php +23 -6
- scb/load.php +6 -5
- storage.php +99 -18
- ui/admin.js +0 -79
- ui/boxes.php +6 -28
- ui/ui.js +9 -1
- ui/ui.php +50 -12
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 = '
|
71 |
-
if ( '
|
|
|
|
|
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 |
-
|
113 |
}
|
114 |
|
115 |
-
function
|
116 |
global $wpdb;
|
117 |
|
118 |
$map = array(
|
@@ -122,12 +122,61 @@ class P2P_Query {
|
|
122 |
);
|
123 |
|
124 |
foreach ( $map as $qv => $direction ) {
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
}
|
128 |
}
|
129 |
|
130 |
-
return $
|
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.
|
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.
|
10 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/posts-to-posts\n"
|
11 |
-
"POT-Creation-Date: 2010-
|
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 |
-
#:
|
20 |
-
msgid "
|
21 |
-
msgstr ""
|
22 |
-
|
23 |
-
#: admin/admin.php:115
|
24 |
-
msgid "No connections."
|
25 |
msgstr ""
|
26 |
|
27 |
-
#:
|
28 |
-
msgid "
|
29 |
msgstr ""
|
30 |
|
31 |
-
#:
|
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 |
-
#:
|
38 |
-
msgid ""
|
39 |
-
"Enter IDs of connected post types separated by commas, or turn on JavaScript!"
|
40 |
msgstr ""
|
41 |
|
42 |
-
#:
|
43 |
-
msgid "
|
44 |
msgstr ""
|
45 |
|
46 |
-
#:
|
47 |
-
msgid "
|
|
|
|
|
48 |
msgstr ""
|
49 |
|
50 |
-
#:
|
51 |
-
msgid "
|
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
|
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.
|
5 |
Plugin Author: scribu
|
6 |
-
Description: Create
|
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.
|
7 |
-
Stable tag: 0.
|
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
|
22 |
-
|
23 |
|
24 |
-
|
25 |
-
|
|
|
26 |
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
* Execute the job with a given delay
|
79 |
-
* @param int
|
|
|
80 |
*/
|
81 |
-
function do_once( $delay = 0 ) {
|
82 |
-
|
83 |
-
|
84 |
|
85 |
-
|
86 |
-
|
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 |
-
$
|
217 |
-
|
218 |
-
|
|
|
|
|
|
|
|
|
|
|
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 (
|
24 |
-
|
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
|
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
|
121 |
-
|
|
|
|
|
|
|
|
|
122 |
$closing = $tag;
|
|
|
123 |
foreach ( $attributes as $key => $value ) {
|
124 |
-
$tag .= ' ' . $key . '="' .
|
125 |
}
|
126 |
} else {
|
127 |
-
$
|
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(
|
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' ),
|
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 (
|
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 |
-
$
|
51 |
-
$where =
|
|
|
52 |
|
53 |
switch ( $to ) {
|
54 |
case 'from':
|
55 |
-
$
|
56 |
$where .= $wpdb->prepare( "p2p_from = %d", $from );
|
57 |
break;
|
58 |
case 'to':
|
59 |
-
$
|
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 =
|
69 |
-
|
70 |
-
|
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 $
|
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
|
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
|
138 |
-
|
139 |
-
|
140 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
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, $
|
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 = $
|
|
|
|
|
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 |
-
$
|
142 |
-
|
143 |
-
|
144 |
-
|
|
|
145 |
} elseif ( $args['reciprocal'] && $post_type == $args['to'] ) {
|
146 |
-
$
|
|
|
|
|
147 |
} else {
|
148 |
-
continue;
|
149 |
}
|
150 |
|
151 |
-
|
|
|
|
|
|
|
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;
|