Version Description
- fixed get_prev() and get_next()
- introduced get_adjacent_items()
- fixed admin column titles
- made admin column titles show up before the post date. props luk3thomas
- added 'help' key to 'from_labels' and 'to_labels' arrays. props tareq1988
Download this release
Release Info
Developer | scribu |
Plugin | Posts 2 Posts |
Version | 1.5.2 |
Comparing to | |
See all releases |
Code changes from version 1.5.1 to 1.5.2
- CONTRIBUTING.md +1 -1
- admin/box.css +5 -0
- admin/box.js +3 -2
- admin/box.php +1 -0
- admin/column.php +2 -4
- admin/factory.php +1 -1
- admin/templates/box.html +2 -0
- core/api.php +2 -37
- autoload.php → core/autoload.php +0 -0
- core/connection-type-factory.php +5 -6
- core/connection-type.php +77 -33
- core/determinate-connection-type.php +24 -0
- core/direction-strategy.php +9 -0
- core/indeterminate-connection-type.php +14 -7
- core/init.php +16 -0
- core/reciprocal-connection-type.php +2 -2
- core/side.php +1 -0
- posts-to-posts.php +5 -19
- readme.txt +17 -12
- scb/Forms.php +12 -3
CONTRIBUTING.md
CHANGED
@@ -8,7 +8,7 @@ Make a fork and clone it:
|
|
8 |
git clone --recurse-submodules git@github.com:{YOUR GITHUB USERNAME}/wp-posts-to-posts.git posts-to-posts
|
9 |
```
|
10 |
|
11 |
-
You can now work on the PHP and CSS files.
|
12 |
|
13 |
### JavaScript
|
14 |
|
8 |
git clone --recurse-submodules git@github.com:{YOUR GITHUB USERNAME}/wp-posts-to-posts.git posts-to-posts
|
9 |
```
|
10 |
|
11 |
+
You can now work on the PHP and CSS files. Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/).
|
12 |
|
13 |
### JavaScript
|
14 |
|
admin/box.css
CHANGED
@@ -19,6 +19,11 @@
|
|
19 |
padding: 10px;
|
20 |
}
|
21 |
|
|
|
|
|
|
|
|
|
|
|
22 |
.p2p-box .p2p-tab-search {
|
23 |
display: block;
|
24 |
}
|
19 |
padding: 10px;
|
20 |
}
|
21 |
|
22 |
+
.p2p-box p.help {
|
23 |
+
color: #666;
|
24 |
+
font-style: normal;
|
25 |
+
}
|
26 |
+
|
27 |
.p2p-box .p2p-tab-search {
|
28 |
display: block;
|
29 |
}
|
admin/box.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
// Generated by CoffeeScript 1.
|
2 |
(function() {
|
3 |
var Candidates, CandidatesView, Connections, ConnectionsView, CreatePostView, ENTER_KEY, MetaboxView, get_mustache_template, remove_row, row_wait;
|
4 |
|
@@ -179,9 +179,10 @@
|
|
179 |
promote: function(ev) {
|
180 |
var $td;
|
181 |
$td = jQuery(ev.target).closest('td');
|
|
|
182 |
row_wait($td);
|
183 |
this.collection.trigger('promote', $td);
|
184 |
-
return
|
185 |
},
|
186 |
handleReturn: function(ev) {
|
187 |
if (ev.keyCode === ENTER_KEY) {
|
1 |
+
// Generated by CoffeeScript 1.6.1
|
2 |
(function() {
|
3 |
var Candidates, CandidatesView, Connections, ConnectionsView, CreatePostView, ENTER_KEY, MetaboxView, get_mustache_template, remove_row, row_wait;
|
4 |
|
179 |
promote: function(ev) {
|
180 |
var $td;
|
181 |
$td = jQuery(ev.target).closest('td');
|
182 |
+
ev.preventDefault();
|
183 |
row_wait($td);
|
184 |
this.collection.trigger('promote', $td);
|
185 |
+
return null;
|
186 |
},
|
187 |
handleReturn: function(ev) {
|
188 |
if (ev.keyCode === ENTER_KEY) {
|
admin/box.php
CHANGED
@@ -74,6 +74,7 @@ class P2P_Box {
|
|
74 |
'attributes' => $this->render_data_attributes(),
|
75 |
'connections' => $this->render_connections_table( $post ),
|
76 |
'create-connections' => $this->render_create_connections( $post ),
|
|
|
77 |
);
|
78 |
|
79 |
echo P2P_Mustache::render( 'box', $data );
|
74 |
'attributes' => $this->render_data_attributes(),
|
75 |
'connections' => $this->render_connections_table( $post ),
|
76 |
'create-connections' => $this->render_create_connections( $post ),
|
77 |
+
'help' => isset( $this->labels->help ) ? $this->labels->help : ''
|
78 |
);
|
79 |
|
80 |
echo P2P_Mustache::render( 'box', $data );
|
admin/column.php
CHANGED
@@ -26,11 +26,9 @@ abstract class P2P_Column {
|
|
26 |
|
27 |
$title = isset( $labels->column_title )
|
28 |
? $labels->column_title
|
29 |
-
: $
|
30 |
|
31 |
-
$columns
|
32 |
-
|
33 |
-
return $columns;
|
34 |
}
|
35 |
|
36 |
protected abstract function get_items();
|
26 |
|
27 |
$title = isset( $labels->column_title )
|
28 |
? $labels->column_title
|
29 |
+
: $this->ctype->get( 'current', 'title' );
|
30 |
|
31 |
+
return array_splice( $columns, 0, -1 ) + array( $this->column_id => $title ) + $columns;
|
|
|
|
|
32 |
}
|
33 |
|
34 |
protected abstract function get_items();
|
admin/factory.php
CHANGED
@@ -97,7 +97,7 @@ abstract class P2P_Factory {
|
|
97 |
if ( !$direction )
|
98 |
return array();
|
99 |
|
100 |
-
return $ctype->
|
101 |
}
|
102 |
}
|
103 |
|
97 |
if ( !$direction )
|
98 |
return array();
|
99 |
|
100 |
+
return $ctype->strategy->directions_for_admin( $direction, $show_ui );
|
101 |
}
|
102 |
}
|
103 |
|
admin/templates/box.html
CHANGED
@@ -1,4 +1,6 @@
|
|
1 |
<div class="p2p-box" {{attributes}}>
|
|
|
|
|
2 |
{{#connections}}
|
3 |
<table class="p2p-connections" {{{hide}}}>
|
4 |
<thead>
|
1 |
<div class="p2p-box" {{attributes}}>
|
2 |
+
<p class="help">{{help}}</p>
|
3 |
+
|
4 |
{{#connections}}
|
5 |
<table class="p2p-connections" {{{hide}}}>
|
6 |
<thead>
|
core/api.php
CHANGED
@@ -3,44 +3,9 @@
|
|
3 |
/**
|
4 |
* Register a connection type.
|
5 |
*
|
6 |
-
* @
|
7 |
-
*
|
8 |
-
* - 'name' - string A unique identifier for this connection type.
|
9 |
-
*
|
10 |
-
* - 'from' - string|array The first end of the connection: post type name or 'user'
|
11 |
-
*
|
12 |
-
* - 'from_query_vars' - array Additional query vars to pass to WP_Query. Default: none.
|
13 |
-
*
|
14 |
-
* - 'to' - string|array The second end of the connection: post type name or 'user'
|
15 |
-
*
|
16 |
-
* - 'to_query_vars' - array Additional query vars to pass to WP_Query. Default: none.
|
17 |
-
*
|
18 |
-
* - 'fields' - array( key => Title ) Metadata fields editable by the user. Default: none.
|
19 |
-
*
|
20 |
-
* - 'cardinality' - string How many connection can each post have: 'one-to-many', 'many-to-one' or 'many-to-many'. Default: 'many-to-many'
|
21 |
-
*
|
22 |
-
* - 'duplicate_connections' - bool Whether to allow more than one connection between the same two posts. Default: false.
|
23 |
-
*
|
24 |
-
* - 'self_connections' - bool Whether to allow a post/user to connect to itself. Default: false.
|
25 |
-
*
|
26 |
-
* - 'sortable' - bool|string Whether to allow connections to be ordered via drag-and-drop. Can be 'from', 'to', 'any' or false. Default: false.
|
27 |
-
*
|
28 |
-
* - 'title' - string|array The box's title. Default: 'Connected {$post_type}s'
|
29 |
-
*
|
30 |
-
* - 'from_labels' - array Additional labels for the admin box (optional)
|
31 |
-
*
|
32 |
-
* - 'to_labels' - array Additional labels for the admin box (optional)
|
33 |
-
*
|
34 |
-
* - 'reciprocal' - bool For indeterminate connections: True means all connections are displayed in a single box. False means 'from' connections are shown in one box and 'to' connections are shown in another box. Default: false.
|
35 |
-
*
|
36 |
-
* - 'admin_box' - bool|string|array Whether and where to show the admin connections box. Default: 'any'
|
37 |
-
*
|
38 |
-
* - 'can_create_post' - bool Whether to allow post creation via the connection box. Default: true.
|
39 |
-
*
|
40 |
-
* - 'admin_column' - bool|string|array Whether to show connection columns on post/user list table. Default: false
|
41 |
-
*
|
42 |
-
* - 'admin_dropdown' - bool|string|array Whether to show connection dropdown on post/user list table. Default: false
|
43 |
*
|
|
|
44 |
* @return bool|object False on failure, P2P_Connection_Type instance on success.
|
45 |
*/
|
46 |
function p2p_register_connection_type( $args ) {
|
3 |
/**
|
4 |
* Register a connection type.
|
5 |
*
|
6 |
+
* @link https://github.com/scribu/wp-posts-to-posts/wiki/p2p_register_connection_type
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
*
|
8 |
+
* @param array $args
|
9 |
* @return bool|object False on failure, P2P_Connection_Type instance on success.
|
10 |
*/
|
11 |
function p2p_register_connection_type( $args ) {
|
autoload.php → core/autoload.php
RENAMED
File without changes
|
core/connection-type-factory.php
CHANGED
@@ -43,9 +43,8 @@ class P2P_Connection_Type_Factory {
|
|
43 |
|
44 |
$args = apply_filters( 'p2p_connection_type_args', $args, $sides );
|
45 |
|
46 |
-
$
|
47 |
-
|
48 |
-
$ctype = new $class( $args, $sides );
|
49 |
|
50 |
self::$instances[ $ctype->name ] = $ctype;
|
51 |
|
@@ -82,7 +81,7 @@ class P2P_Connection_Type_Factory {
|
|
82 |
return md5( serialize( $vals ) );
|
83 |
}
|
84 |
|
85 |
-
private static function
|
86 |
if ( $sides['from']->is_same_type( $sides['to'] ) &&
|
87 |
$sides['from']->is_indeterminate( $sides['to'] ) ) {
|
88 |
if ( $reciprocal )
|
@@ -90,10 +89,10 @@ class P2P_Connection_Type_Factory {
|
|
90 |
else
|
91 |
$class = 'P2P_Indeterminate_Connection_Type';
|
92 |
} else {
|
93 |
-
$class = '
|
94 |
}
|
95 |
|
96 |
-
return $class;
|
97 |
}
|
98 |
|
99 |
public static function get_all_instances() {
|
43 |
|
44 |
$args = apply_filters( 'p2p_connection_type_args', $args, $sides );
|
45 |
|
46 |
+
$ctype = new P2P_Connection_Type( $args, $sides );
|
47 |
+
$ctype->strategy = self::get_direction_strategy( $sides, _p2p_pluck( $args, 'reciprocal' ) );
|
|
|
48 |
|
49 |
self::$instances[ $ctype->name ] = $ctype;
|
50 |
|
81 |
return md5( serialize( $vals ) );
|
82 |
}
|
83 |
|
84 |
+
private static function get_direction_strategy( $sides, $reciprocal ) {
|
85 |
if ( $sides['from']->is_same_type( $sides['to'] ) &&
|
86 |
$sides['from']->is_indeterminate( $sides['to'] ) ) {
|
87 |
if ( $reciprocal )
|
89 |
else
|
90 |
$class = 'P2P_Indeterminate_Connection_Type';
|
91 |
} else {
|
92 |
+
$class = 'P2P_Determinate_Connection_Type';
|
93 |
}
|
94 |
|
95 |
+
return new $class;
|
96 |
}
|
97 |
|
98 |
public static function get_all_instances() {
|
core/connection-type.php
CHANGED
@@ -2,10 +2,6 @@
|
|
2 |
|
3 |
class P2P_Connection_Type {
|
4 |
|
5 |
-
protected $directed_class = 'P2P_Directed_Connection_Type';
|
6 |
-
|
7 |
-
protected $arrow = '→';
|
8 |
-
|
9 |
public $side;
|
10 |
|
11 |
public $cardinality;
|
@@ -50,13 +46,6 @@ class P2P_Connection_Type {
|
|
50 |
return $value[ $direction ];
|
51 |
}
|
52 |
|
53 |
-
function _directions_for_admin( $direction, $show_ui ) {
|
54 |
-
return array_intersect(
|
55 |
-
_p2p_expand_direction( $show_ui ),
|
56 |
-
_p2p_expand_direction( $direction )
|
57 |
-
);
|
58 |
-
}
|
59 |
-
|
60 |
private function set_self_connections( &$args ) {
|
61 |
$from_side = $this->side['from'];
|
62 |
$to_side = $this->side['to'];
|
@@ -128,13 +117,17 @@ class P2P_Connection_Type {
|
|
128 |
return;
|
129 |
}
|
130 |
|
131 |
-
|
132 |
-
|
133 |
-
if ( !$directed ) {
|
134 |
trigger_error( sprintf( "Can't determine direction for '%s' type.", $this->name ), E_USER_WARNING );
|
135 |
return false;
|
136 |
}
|
137 |
|
|
|
|
|
|
|
|
|
|
|
138 |
return call_user_func_array( array( $directed, $method ), $args );
|
139 |
}
|
140 |
|
@@ -150,7 +143,7 @@ class P2P_Connection_Type {
|
|
150 |
return false;
|
151 |
|
152 |
if ( $instantiate ) {
|
153 |
-
$class = $this->
|
154 |
|
155 |
return new $class( $this, $direction );
|
156 |
}
|
@@ -168,9 +161,6 @@ class P2P_Connection_Type {
|
|
168 |
* @return bool|object|string False on failure, P2P_Directed_Connection_Type instance or direction on success.
|
169 |
*/
|
170 |
public function find_direction( $arg, $instantiate = true, $object_type = null ) {
|
171 |
-
if ( is_array( $arg ) )
|
172 |
-
$arg = reset( $arg );
|
173 |
-
|
174 |
if ( $object_type ) {
|
175 |
$direction = $this->direction_from_object_type( $object_type );
|
176 |
if ( !$direction )
|
@@ -180,26 +170,26 @@ class P2P_Connection_Type {
|
|
180 |
return $this->set_direction( $direction, $instantiate );
|
181 |
}
|
182 |
|
183 |
-
$
|
|
|
|
|
184 |
|
185 |
-
|
186 |
-
return $this->set_direction( $direction, $instantiate );
|
187 |
|
188 |
-
return
|
189 |
-
}
|
190 |
-
|
191 |
-
protected function choose_direction( $direction ) {
|
192 |
-
return $direction;
|
193 |
}
|
194 |
|
195 |
protected function direction_from_item( $arg ) {
|
|
|
|
|
|
|
196 |
foreach ( array( 'from', 'to' ) as $direction ) {
|
197 |
$item = $this->side[ $direction ]->item_recognize( $arg );
|
198 |
|
199 |
if ( !$item )
|
200 |
continue;
|
201 |
|
202 |
-
return $this->choose_direction( $direction );
|
203 |
}
|
204 |
|
205 |
return false;
|
@@ -226,7 +216,7 @@ class P2P_Connection_Type {
|
|
226 |
if ( !$this->_type_check( $direction, $object_type, $post_types ) )
|
227 |
continue;
|
228 |
|
229 |
-
return $this->choose_direction( $direction );
|
230 |
}
|
231 |
|
232 |
return false;
|
@@ -292,10 +282,14 @@ class P2P_Connection_Type {
|
|
292 |
|
293 |
// The direction needs to be based on the second parameter,
|
294 |
// so that it's consistent with $this->connect( $from, $to ) etc.
|
295 |
-
$
|
296 |
-
if ( !$
|
297 |
return false;
|
298 |
|
|
|
|
|
|
|
|
|
299 |
$key = $directed->get_orderby_key();
|
300 |
if ( !$key )
|
301 |
return false;
|
@@ -309,13 +303,63 @@ class P2P_Connection_Type {
|
|
309 |
$adjacent = $directed->get_connected( $to, array(
|
310 |
'connected_meta' => array(
|
311 |
array(
|
312 |
-
'key' => $
|
313 |
'value' => $order + $which
|
314 |
)
|
315 |
)
|
316 |
), 'abstract' );
|
317 |
|
318 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
}
|
320 |
|
321 |
/**
|
@@ -385,7 +429,7 @@ class P2P_Connection_Type {
|
|
385 |
$desc[ $key ] = $this->side[ $key ]->get_desc();
|
386 |
}
|
387 |
|
388 |
-
$label = sprintf( '%s %s %s', $desc['from'], $this->
|
389 |
|
390 |
$title = $this->get_field( 'title', 'from' );
|
391 |
|
2 |
|
3 |
class P2P_Connection_Type {
|
4 |
|
|
|
|
|
|
|
|
|
5 |
public $side;
|
6 |
|
7 |
public $cardinality;
|
46 |
return $value[ $direction ];
|
47 |
}
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
private function set_self_connections( &$args ) {
|
50 |
$from_side = $this->side['from'];
|
51 |
$to_side = $this->side['to'];
|
117 |
return;
|
118 |
}
|
119 |
|
120 |
+
$r = $this->direction_from_item( $args[0] );
|
121 |
+
if ( !$r ) {
|
|
|
122 |
trigger_error( sprintf( "Can't determine direction for '%s' type.", $this->name ), E_USER_WARNING );
|
123 |
return false;
|
124 |
}
|
125 |
|
126 |
+
// replace the first argument with the normalized one, to avoid having to do it again
|
127 |
+
list( $direction, $args[0] ) = $r;
|
128 |
+
|
129 |
+
$directed = $this->set_direction( $direction );
|
130 |
+
|
131 |
return call_user_func_array( array( $directed, $method ), $args );
|
132 |
}
|
133 |
|
143 |
return false;
|
144 |
|
145 |
if ( $instantiate ) {
|
146 |
+
$class = $this->strategy->get_directed_class();
|
147 |
|
148 |
return new $class( $this, $direction );
|
149 |
}
|
161 |
* @return bool|object|string False on failure, P2P_Directed_Connection_Type instance or direction on success.
|
162 |
*/
|
163 |
public function find_direction( $arg, $instantiate = true, $object_type = null ) {
|
|
|
|
|
|
|
164 |
if ( $object_type ) {
|
165 |
$direction = $this->direction_from_object_type( $object_type );
|
166 |
if ( !$direction )
|
170 |
return $this->set_direction( $direction, $instantiate );
|
171 |
}
|
172 |
|
173 |
+
$r = $this->direction_from_item( $arg );
|
174 |
+
if ( !$r )
|
175 |
+
return false;
|
176 |
|
177 |
+
list( $direction, $item ) = $r;
|
|
|
178 |
|
179 |
+
return $this->set_direction( $direction, $instantiate );
|
|
|
|
|
|
|
|
|
180 |
}
|
181 |
|
182 |
protected function direction_from_item( $arg ) {
|
183 |
+
if ( is_array( $arg ) )
|
184 |
+
$arg = reset( $arg );
|
185 |
+
|
186 |
foreach ( array( 'from', 'to' ) as $direction ) {
|
187 |
$item = $this->side[ $direction ]->item_recognize( $arg );
|
188 |
|
189 |
if ( !$item )
|
190 |
continue;
|
191 |
|
192 |
+
return array( $this->strategy->choose_direction( $direction ), $item );
|
193 |
}
|
194 |
|
195 |
return false;
|
216 |
if ( !$this->_type_check( $direction, $object_type, $post_types ) )
|
217 |
continue;
|
218 |
|
219 |
+
return $this->strategy->choose_direction( $direction );
|
220 |
}
|
221 |
|
222 |
return false;
|
282 |
|
283 |
// The direction needs to be based on the second parameter,
|
284 |
// so that it's consistent with $this->connect( $from, $to ) etc.
|
285 |
+
$r = $this->direction_from_item( $to );
|
286 |
+
if ( !$r )
|
287 |
return false;
|
288 |
|
289 |
+
list( $direction, $to ) = $r;
|
290 |
+
|
291 |
+
$directed = $this->set_direction( $direction );
|
292 |
+
|
293 |
$key = $directed->get_orderby_key();
|
294 |
if ( !$key )
|
295 |
return false;
|
303 |
$adjacent = $directed->get_connected( $to, array(
|
304 |
'connected_meta' => array(
|
305 |
array(
|
306 |
+
'key' => $key,
|
307 |
'value' => $order + $which
|
308 |
)
|
309 |
)
|
310 |
), 'abstract' );
|
311 |
|
312 |
+
if ( empty( $adjacent->items ) )
|
313 |
+
return false;
|
314 |
+
|
315 |
+
$item = reset( $adjacent->items );
|
316 |
+
|
317 |
+
return $item->get_object();
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Get the previous, next and parent items, in an ordered connection type.
|
322 |
+
*
|
323 |
+
* @param mixed The current item
|
324 |
+
*
|
325 |
+
* @return bool|array False if the connections aren't sortable,
|
326 |
+
* associative array otherwise:
|
327 |
+
* array(
|
328 |
+
* 'parent' => bool|object
|
329 |
+
* 'previous' => bool|object
|
330 |
+
* 'next' => bool|object
|
331 |
+
* )
|
332 |
+
*/
|
333 |
+
public function get_adjacent_items( $item ) {
|
334 |
+
$result = array(
|
335 |
+
'parent' => false,
|
336 |
+
'previous' => false,
|
337 |
+
'next' => false,
|
338 |
+
);
|
339 |
+
|
340 |
+
$r = $this->direction_from_item( $item );
|
341 |
+
if ( !$r )
|
342 |
+
return false;
|
343 |
+
|
344 |
+
list( $direction, $item ) = $r;
|
345 |
+
|
346 |
+
$connected_series = $this->set_direction( $direction )->get_connected( $item,
|
347 |
+
array(), 'abstract' )->items;
|
348 |
+
|
349 |
+
if ( empty( $connected_series ) )
|
350 |
+
return $r;
|
351 |
+
|
352 |
+
if ( count( $connected_series ) > 1 ) {
|
353 |
+
trigger_error( 'More than one connected parents found.', E_USER_WARNING );
|
354 |
+
}
|
355 |
+
|
356 |
+
$parent = $connected_series[0];
|
357 |
+
|
358 |
+
$result['parent'] = $parent->get_object();
|
359 |
+
$result['previous'] = $this->get_previous( $item->ID, $parent->ID );
|
360 |
+
$result['next'] = $this->get_next( $item, $parent );
|
361 |
+
|
362 |
+
return $result;
|
363 |
}
|
364 |
|
365 |
/**
|
429 |
$desc[ $key ] = $this->side[ $key ]->get_desc();
|
430 |
}
|
431 |
|
432 |
+
$label = sprintf( '%s %s %s', $desc['from'], $this->strategy->get_arrow(), $desc['to'] );
|
433 |
|
434 |
$title = $this->get_field( 'title', 'from' );
|
435 |
|
core/determinate-connection-type.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class P2P_Determinate_Connection_Type implements P2P_Direction_Strategy {
|
4 |
+
|
5 |
+
function get_arrow() {
|
6 |
+
return '→';
|
7 |
+
}
|
8 |
+
|
9 |
+
function choose_direction( $direction ) {
|
10 |
+
return $direction;
|
11 |
+
}
|
12 |
+
|
13 |
+
function directions_for_admin( $direction, $show_ui ) {
|
14 |
+
return array_intersect(
|
15 |
+
_p2p_expand_direction( $show_ui ),
|
16 |
+
_p2p_expand_direction( $direction )
|
17 |
+
);
|
18 |
+
}
|
19 |
+
|
20 |
+
function get_directed_class() {
|
21 |
+
return 'P2P_Directed_Connection_Type';
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
core/direction-strategy.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface P2P_Direction_Strategy {
|
4 |
+
function get_arrow();
|
5 |
+
function choose_direction( $direction );
|
6 |
+
function directions_for_admin( $direction, $show_ui );
|
7 |
+
function get_directed_class();
|
8 |
+
}
|
9 |
+
|
core/indeterminate-connection-type.php
CHANGED
@@ -1,17 +1,24 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class P2P_Indeterminate_Connection_Type
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
|
9 |
-
|
10 |
return 'from';
|
11 |
}
|
12 |
|
13 |
-
function
|
14 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
16 |
}
|
17 |
|
1 |
<?php
|
2 |
|
3 |
+
class P2P_Indeterminate_Connection_Type implements P2P_Direction_Strategy {
|
4 |
|
5 |
+
function get_arrow() {
|
6 |
+
return '↔';
|
7 |
+
}
|
8 |
|
9 |
+
function choose_direction( $direction ) {
|
10 |
return 'from';
|
11 |
}
|
12 |
|
13 |
+
function directions_for_admin( $_, $show_ui ) {
|
14 |
+
return array_intersect(
|
15 |
+
_p2p_expand_direction( $show_ui ),
|
16 |
+
_p2p_expand_direction( 'any' )
|
17 |
+
);
|
18 |
+
}
|
19 |
+
|
20 |
+
function get_directed_class() {
|
21 |
+
return 'P2P_Indeterminate_Directed_Connection_Type';
|
22 |
}
|
23 |
}
|
24 |
|
core/init.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once dirname( __FILE__ ) . '/util.php';
|
4 |
+
require_once dirname( __FILE__ ) . '/api.php';
|
5 |
+
require_once dirname( __FILE__ ) . '/autoload.php';
|
6 |
+
|
7 |
+
P2P_Autoload::register( 'P2P_', dirname( __FILE__ ) );
|
8 |
+
|
9 |
+
P2P_Storage::init();
|
10 |
+
|
11 |
+
P2P_Query_Post::init();
|
12 |
+
P2P_Query_User::init();
|
13 |
+
|
14 |
+
P2P_Widget::init();
|
15 |
+
P2P_Shortcodes::init();
|
16 |
+
|
core/reciprocal-connection-type.php
CHANGED
@@ -2,11 +2,11 @@
|
|
2 |
|
3 |
class P2P_Reciprocal_Connection_Type extends P2P_Indeterminate_Connection_Type {
|
4 |
|
5 |
-
|
6 |
return 'any';
|
7 |
}
|
8 |
|
9 |
-
function
|
10 |
if ( $show_ui )
|
11 |
$directions = array( 'any' );
|
12 |
else
|
2 |
|
3 |
class P2P_Reciprocal_Connection_Type extends P2P_Indeterminate_Connection_Type {
|
4 |
|
5 |
+
function choose_direction( $direction ) {
|
6 |
return 'any';
|
7 |
}
|
8 |
|
9 |
+
function directions_for_admin( $direction, $show_ui ) {
|
10 |
if ( $show_ui )
|
11 |
$directions = array( 'any' );
|
12 |
else
|
core/side.php
CHANGED
@@ -27,6 +27,7 @@ abstract class P2P_Side {
|
|
27 |
|
28 |
/**
|
29 |
* @param object Raw object or P2P_Item
|
|
|
30 |
*/
|
31 |
function item_recognize( $arg ) {
|
32 |
$class = $this->item_type;
|
27 |
|
28 |
/**
|
29 |
* @param object Raw object or P2P_Item
|
30 |
+
* @return bool|P2P_Item
|
31 |
*/
|
32 |
function item_recognize( $arg ) {
|
33 |
$class = $this->item_type;
|
posts-to-posts.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
Plugin Name: Posts 2 Posts
|
4 |
Description: Create many-to-many relationships between all types of posts.
|
5 |
-
Version: 1.5.
|
6 |
Author: scribu
|
7 |
Author URI: http://scribu.net/
|
8 |
Plugin URI: http://scribu.net/wordpress/posts-to-posts
|
@@ -10,35 +10,21 @@ Text Domain: posts-to-posts
|
|
10 |
Domain Path: /lang
|
11 |
*/
|
12 |
|
13 |
-
define( 'P2P_PLUGIN_VERSION', '1.5' );
|
14 |
|
15 |
define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
|
16 |
|
17 |
require_once dirname( __FILE__ ) . '/scb/load.php';
|
18 |
|
19 |
function _p2p_load() {
|
20 |
-
|
21 |
|
22 |
-
|
23 |
|
24 |
-
|
25 |
-
require_once $base . '/core/api.php';
|
26 |
-
require_once $base . '/autoload.php';
|
27 |
-
|
28 |
-
P2P_Autoload::register( 'P2P_', $base . '/core' );
|
29 |
-
|
30 |
-
P2P_Storage::init();
|
31 |
-
|
32 |
-
P2P_Query_Post::init();
|
33 |
-
P2P_Query_User::init();
|
34 |
-
|
35 |
-
P2P_Widget::init();
|
36 |
-
P2P_Shortcodes::init();
|
37 |
|
38 |
if ( is_admin() )
|
39 |
_p2p_load_admin();
|
40 |
-
|
41 |
-
register_uninstall_hook( __FILE__, array( 'P2P_Storage', 'uninstall' ) );
|
42 |
}
|
43 |
scb_init( '_p2p_load' );
|
44 |
|
2 |
/*
|
3 |
Plugin Name: Posts 2 Posts
|
4 |
Description: Create many-to-many relationships between all types of posts.
|
5 |
+
Version: 1.5.2
|
6 |
Author: scribu
|
7 |
Author URI: http://scribu.net/
|
8 |
Plugin URI: http://scribu.net/wordpress/posts-to-posts
|
10 |
Domain Path: /lang
|
11 |
*/
|
12 |
|
13 |
+
define( 'P2P_PLUGIN_VERSION', '1.5.2' );
|
14 |
|
15 |
define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
|
16 |
|
17 |
require_once dirname( __FILE__ ) . '/scb/load.php';
|
18 |
|
19 |
function _p2p_load() {
|
20 |
+
load_plugin_textdomain( P2P_TEXTDOMAIN, '', basename( dirname( __FILE__ ) ) . '/lang' );
|
21 |
|
22 |
+
require_once dirname( __FILE__ ) . '/core/init.php';
|
23 |
|
24 |
+
register_uninstall_hook( __FILE__, array( 'P2P_Storage', 'uninstall' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
if ( is_admin() )
|
27 |
_p2p_load_admin();
|
|
|
|
|
28 |
}
|
29 |
scb_init( '_p2p_load' );
|
30 |
|
readme.txt
CHANGED
@@ -1,11 +1,12 @@
|
|
1 |
=== Posts 2 Posts ===
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
License
|
|
|
9 |
|
10 |
Efficient many-to-many connections between posts, pages, custom post types, users.
|
11 |
|
@@ -36,12 +37,9 @@ Additional info can be found on the [wiki](http://github.com/scribu/wp-posts-to-
|
|
36 |
|
37 |
== Frequently Asked Questions ==
|
38 |
|
39 |
-
=
|
40 |
-
|
41 |
-
Make sure your host is running PHP 5. The only foolproof way to do this is to add this line to wp-config.php:
|
42 |
|
43 |
-
|
44 |
-
<br>
|
45 |
|
46 |
== Screenshots ==
|
47 |
|
@@ -53,6 +51,13 @@ Make sure your host is running PHP 5. The only foolproof way to do this is to ad
|
|
53 |
|
54 |
== Changelog ==
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
= 1.5.1 =
|
57 |
* fix fatal error on activation. props benmay
|
58 |
|
1 |
=== Posts 2 Posts ===
|
2 |
+
|
3 |
+
Contributors: scribu, ciobi
|
4 |
+
Tags: connections, custom post types, relationships, many-to-many, users
|
5 |
+
Requires at least: 3.5
|
6 |
+
Tested up to: 3.5
|
7 |
+
Stable tag: 1.5.2
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
11 |
Efficient many-to-many connections between posts, pages, custom post types, users.
|
12 |
|
37 |
|
38 |
== Frequently Asked Questions ==
|
39 |
|
40 |
+
= The waiting icon keeps spinning forever. =
|
|
|
|
|
41 |
|
42 |
+
[Check for JavaScript errors](http://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors). If it's an AJAX request, check its output.
|
|
|
43 |
|
44 |
== Screenshots ==
|
45 |
|
51 |
|
52 |
== Changelog ==
|
53 |
|
54 |
+
= 1.5.2 =
|
55 |
+
* fixed get_prev() and get_next()
|
56 |
+
* introduced get_adjacent_items()
|
57 |
+
* fixed admin column titles
|
58 |
+
* made admin column titles show up before the post date. props luk3thomas
|
59 |
+
* added 'help' key to 'from_labels' and 'to_labels' arrays. props tareq1988
|
60 |
+
|
61 |
= 1.5.1 =
|
62 |
* fix fatal error on activation. props benmay
|
63 |
|
scb/Forms.php
CHANGED
@@ -662,9 +662,14 @@ abstract class scbSingleChoiceField extends scbFormField {
|
|
662 |
protected function _render( $args ) {
|
663 |
$args = wp_parse_args( $args, array(
|
664 |
'numeric' => false, // use numeric array instead of associative
|
665 |
-
'selected' => array( 'foo' ), // hack to make default blank
|
666 |
) );
|
667 |
|
|
|
|
|
|
|
|
|
|
|
|
|
668 |
return $this->_render_specific( $args );
|
669 |
}
|
670 |
|
@@ -705,12 +710,14 @@ class scbSelectField extends scbSingleChoiceField {
|
|
705 |
if ( false !== $args['text'] ) {
|
706 |
$options[] = array(
|
707 |
'value' => '',
|
708 |
-
'selected' => ( $args['selected']
|
709 |
'title' => $args['text'],
|
710 |
);
|
711 |
}
|
712 |
|
713 |
foreach ( $args['choices'] as $value => $title ) {
|
|
|
|
|
714 |
$options[] = array(
|
715 |
'value' => $value,
|
716 |
'selected' => ( $value == $args['selected'] ),
|
@@ -743,13 +750,15 @@ class scbRadiosField extends scbSelectField {
|
|
743 |
*/
|
744 |
protected function _render_specific( $args ) {
|
745 |
|
746 |
-
if ( array( 'foo' )
|
747 |
// radio buttons should always have one option selected
|
748 |
$args['selected'] = key( $args['choices'] );
|
749 |
}
|
750 |
|
751 |
$opts = '';
|
752 |
foreach ( $args['choices'] as $value => $title ) {
|
|
|
|
|
753 |
$single_input = scbFormField::_checkbox( array(
|
754 |
'name' => $args['name'],
|
755 |
'type' => 'radio',
|
662 |
protected function _render( $args ) {
|
663 |
$args = wp_parse_args( $args, array(
|
664 |
'numeric' => false, // use numeric array instead of associative
|
|
|
665 |
) );
|
666 |
|
667 |
+
if ( isset( $args['selected'] ) ) {
|
668 |
+
$args['selected'] = (string) $args['selected'];
|
669 |
+
} else {
|
670 |
+
$args['selected'] = array('foo'); // hack to make default blank
|
671 |
+
}
|
672 |
+
|
673 |
return $this->_render_specific( $args );
|
674 |
}
|
675 |
|
710 |
if ( false !== $args['text'] ) {
|
711 |
$options[] = array(
|
712 |
'value' => '',
|
713 |
+
'selected' => ( $args['selected'] === array( 'foo' ) ),
|
714 |
'title' => $args['text'],
|
715 |
);
|
716 |
}
|
717 |
|
718 |
foreach ( $args['choices'] as $value => $title ) {
|
719 |
+
$value = (string) $value;
|
720 |
+
|
721 |
$options[] = array(
|
722 |
'value' => $value,
|
723 |
'selected' => ( $value == $args['selected'] ),
|
750 |
*/
|
751 |
protected function _render_specific( $args ) {
|
752 |
|
753 |
+
if ( array( 'foo' ) === $args['selected'] ) {
|
754 |
// radio buttons should always have one option selected
|
755 |
$args['selected'] = key( $args['choices'] );
|
756 |
}
|
757 |
|
758 |
$opts = '';
|
759 |
foreach ( $args['choices'] as $value => $title ) {
|
760 |
+
$value = (string) $value;
|
761 |
+
|
762 |
$single_input = scbFormField::_checkbox( array(
|
763 |
'name' => $args['name'],
|
764 |
'type' => 'radio',
|