Posts 2 Posts - Version 1.4.3

Version Description

  • various bug fixes
  • added 'inline' mode for shortcodes
  • replaced 'trash' icon with 'minus' icon
  • pass direction to 'default_cb'
Download this release

Release Info

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

Code changes from version 1.4.2 to 1.4.3

CONTRIBUTING.md ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This guide is meant for developers wanting to work on the plugin code.
2
+
3
+ ### Setup
4
+
5
+ Make a fork and clone it:
6
+
7
+ ```
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
+
15
+ Don't modify `admin/box.js` directly. Instead:
16
+
17
+ - [Install node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager).
18
+
19
+ - Install [CoffeeScript](http://coffeescript.org):
20
+
21
+ ```
22
+ npm install -g coffee-script
23
+ ```
24
+
25
+ and edit the `admin/box.coffee` file. To compile it, run:
26
+
27
+ ```
28
+ coffee -c admin
29
+ ```
30
+
31
+ ### Testing
32
+
33
+ The plugin comes with a few unit tests.
34
+
35
+ 1. Install [PHPUnit](https://github.com/sebastianbergmann/phpunit/).
36
+ 2. Create `tests/wp-tests-config.php` file. ([sample](https://unit-tests.svn.wordpress.org/trunk/wp-tests-config-sample.php))
37
+ 3. [Install the scbFramework](https://github.com/scribu/wp-scb-framework/wiki) in the mu-plugins dir.
38
+ 4. Run `./bin/test`
admin/box-factory.php CHANGED
@@ -5,14 +5,14 @@ define( 'P2P_BOX_NONCE', 'p2p-box' );
5
  class P2P_Box_Factory extends P2P_Factory {
6
 
7
  function __construct() {
8
- add_filter( 'p2p_connection_type_args', array( $this, 'filter_ctypes' ) );
9
 
10
  add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
11
  add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
12
  add_action( 'wp_ajax_p2p_box', array( $this, 'wp_ajax_p2p_box' ) );
13
  }
14
 
15
- function filter_ctypes( $args ) {
16
  if ( isset( $args['admin_box'] ) ) {
17
  $box_args = _p2p_pluck( $args, 'admin_box' );
18
  if ( !is_array( $box_args ) )
@@ -34,7 +34,7 @@ class P2P_Box_Factory extends P2P_Factory {
34
  'can_create_post' => true
35
  ) );
36
 
37
- $this->register( $args['name'], $box_args );
38
 
39
  return $args;
40
  }
@@ -71,7 +71,8 @@ class P2P_Box_Factory extends P2P_Factory {
71
  private function create_box( $directed ) {
72
  $box_args = $this->queue[ $directed->name ];
73
 
74
- $title_class = 'P2P_Field_Title_' . ucfirst( $directed->get( 'opposite', 'object' ) );
 
75
 
76
  $columns = array(
77
  'delete' => new P2P_Field_Delete,
5
  class P2P_Box_Factory extends P2P_Factory {
6
 
7
  function __construct() {
8
+ add_action( 'p2p_registered_connection_type', array( $this, 'filter_ctypes' ), 10, 2 );
9
 
10
  add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
11
  add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
12
  add_action( 'wp_ajax_p2p_box', array( $this, 'wp_ajax_p2p_box' ) );
13
  }
14
 
15
+ function filter_ctypes( $ctype, $args ) {
16
  if ( isset( $args['admin_box'] ) ) {
17
  $box_args = _p2p_pluck( $args, 'admin_box' );
18
  if ( !is_array( $box_args ) )
34
  'can_create_post' => true
35
  ) );
36
 
37
+ $this->register( $ctype->name, $box_args );
38
 
39
  return $args;
40
  }
71
  private function create_box( $directed ) {
72
  $box_args = $this->queue[ $directed->name ];
73
 
74
+ $title_class = str_replace( 'P2P_Side_', 'P2P_Field_Title_',
75
+ get_class( $directed->get( 'opposite', 'side' ) ) );
76
 
77
  $columns = array(
78
  'delete' => new P2P_Field_Delete,
admin/box.css CHANGED
@@ -117,11 +117,11 @@ td.p2p-col-create .p2p-icon {
117
  }
118
 
119
  .p2p-col-delete .p2p-icon {
120
- background: url("images/delete.png") no-repeat scroll 50% 50% transparent;
121
  }
122
 
123
  .p2p-col-create .p2p-icon {
124
- background: url("images/add.png") no-repeat scroll 50% 50% transparent;
125
  float: left;
126
  margin-right: 6px;
127
  }
117
  }
118
 
119
  .p2p-col-delete .p2p-icon {
120
+ background: url("images/minus.png") no-repeat scroll 50% 50% transparent;
121
  }
122
 
123
  .p2p-col-create .p2p-icon {
124
+ background: url("images/plus.png") no-repeat scroll 50% 50% transparent;
125
  float: left;
126
  margin-right: 6px;
127
  }
admin/box.php CHANGED
@@ -12,6 +12,8 @@ class P2P_Box {
12
 
13
  private $columns;
14
 
 
 
15
  private static $admin_box_qv = array(
16
  'update_post_term_cache' => false,
17
  'update_post_meta_cache' => false,
@@ -29,6 +31,10 @@ class P2P_Box {
29
  }
30
 
31
  public function init_scripts() {
 
 
 
 
32
  wp_enqueue_style( 'p2p-box', plugins_url( 'box.css', __FILE__ ), array(), P2P_PLUGIN_VERSION );
33
 
34
  wp_enqueue_script( 'p2p-box', plugins_url( 'box.js', __FILE__ ), array( 'jquery' ), P2P_PLUGIN_VERSION, true );
@@ -37,6 +43,9 @@ class P2P_Box {
37
  'spinner' => admin_url( 'images/wpspin_light.gif' ),
38
  'deleteConfirmMessage' => __( 'Are you sure you want to delete all connections?', P2P_TEXTDOMAIN ),
39
  ) );
 
 
 
40
  }
41
 
42
  function render( $post ) {
12
 
13
  private $columns;
14
 
15
+ private static $enqueued_scripts = false;
16
+
17
  private static $admin_box_qv = array(
18
  'update_post_term_cache' => false,
19
  'update_post_meta_cache' => false,
31
  }
32
 
33
  public function init_scripts() {
34
+
35
+ if ( self::$enqueued_scripts )
36
+ return;
37
+
38
  wp_enqueue_style( 'p2p-box', plugins_url( 'box.css', __FILE__ ), array(), P2P_PLUGIN_VERSION );
39
 
40
  wp_enqueue_script( 'p2p-box', plugins_url( 'box.js', __FILE__ ), array( 'jquery' ), P2P_PLUGIN_VERSION, true );
43
  'spinner' => admin_url( 'images/wpspin_light.gif' ),
44
  'deleteConfirmMessage' => __( 'Are you sure you want to delete all connections?', P2P_TEXTDOMAIN ),
45
  ) );
46
+
47
+ self::$enqueued_scripts = true;
48
+
49
  }
50
 
51
  function render( $post ) {
admin/column-factory.php CHANGED
@@ -3,12 +3,12 @@
3
  class P2P_Column_Factory extends P2P_Factory {
4
 
5
  function __construct() {
6
- add_filter( 'p2p_connection_type_args', array( $this, 'filter_ctypes' ) );
7
 
8
  add_action( 'admin_print_styles', array( $this, 'add_columns' ) );
9
  }
10
 
11
- function filter_ctypes( $args ) {
12
  if ( isset( $args['admin_column'] ) ) {
13
  $column_args = _p2p_pluck( $args, 'admin_column' );
14
  if ( !is_array( $column_args ) )
@@ -21,7 +21,7 @@ class P2P_Column_Factory extends P2P_Factory {
21
  'show' => false,
22
  ) );
23
 
24
- $this->register( $args['name'], $column_args );
25
 
26
  return $args;
27
  }
3
  class P2P_Column_Factory extends P2P_Factory {
4
 
5
  function __construct() {
6
+ add_action( 'p2p_registered_connection_type', array( $this, 'filter_ctypes' ), 10, 2 );
7
 
8
  add_action( 'admin_print_styles', array( $this, 'add_columns' ) );
9
  }
10
 
11
+ function filter_ctypes( $ctype, $args ) {
12
  if ( isset( $args['admin_column'] ) ) {
13
  $column_args = _p2p_pluck( $args, 'admin_column' );
14
  if ( !is_array( $column_args ) )
21
  'show' => false,
22
  ) );
23
 
24
+ $this->register( $ctype->name, $column_args );
25
 
26
  return $args;
27
  }
admin/column.php CHANGED
@@ -8,6 +8,10 @@ abstract class P2P_Column {
8
 
9
  function __construct( $directed, $items ) {
10
  $this->ctype = $directed;
 
 
 
 
11
 
12
  $extra_qv = array(
13
  'p2p:per_page' => -1,
@@ -24,10 +28,6 @@ abstract class P2P_Column {
24
  }
25
 
26
  function add_column( $columns ) {
27
- $this->column_id = sprintf( 'p2p-%s-%s',
28
- $this->ctype->get_direction(),
29
- $this->ctype->name
30
- );
31
 
32
  $columns[ $this->column_id ] = $this->ctype->get( 'current', 'title' );
33
 
@@ -37,7 +37,7 @@ abstract class P2P_Column {
37
  function styles() {
38
  ?>
39
  <style type="text/css">
40
- .column-<?php echo $this->ctype->name; ?> ul {
41
  margin-top: 0;
42
  margin-bottom: 0;
43
  }
8
 
9
  function __construct( $directed, $items ) {
10
  $this->ctype = $directed;
11
+ $this->column_id = sprintf( 'p2p-%s-%s',
12
+ $this->ctype->get_direction(),
13
+ $this->ctype->name
14
+ );
15
 
16
  $extra_qv = array(
17
  'p2p:per_page' => -1,
28
  }
29
 
30
  function add_column( $columns ) {
 
 
 
 
31
 
32
  $columns[ $this->column_id ] = $this->ctype->get( 'current', 'title' );
33
 
37
  function styles() {
38
  ?>
39
  <style type="text/css">
40
+ .column-<?php echo $this->column_id; ?> ul {
41
  margin-top: 0;
42
  margin-bottom: 0;
43
  }
admin/factory.php CHANGED
@@ -24,12 +24,7 @@ abstract class P2P_Factory {
24
 
25
  $directions = self::determine_directions( $ctype, $object_type, $post_type, $args->show );
26
 
27
- $title = $ctype->title;
28
-
29
- if ( count( $directions ) > 1 && $title['from'] == $title['to'] ) {
30
- $title['from'] .= __( ' (from)', P2P_TEXTDOMAIN );
31
- $title['to'] .= __( ' (to)', P2P_TEXTDOMAIN );
32
- }
33
 
34
  foreach ( $directions as $direction ) {
35
  $key = ( 'to' == $direction ) ? 'to' : 'from';
@@ -41,28 +36,26 @@ abstract class P2P_Factory {
41
  }
42
  }
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  protected static function determine_directions( $ctype, $object_type, $post_type, $show_ui ) {
45
  $direction = $ctype->direction_from_types( $object_type, $post_type );
46
  if ( !$direction )
47
  return array();
48
 
49
- if ( $ctype->indeterminate && $ctype->reciprocal ) {
50
- if ( $show_ui )
51
- $directions = array( 'any' );
52
- else
53
- $directions = array();
54
- } else {
55
- if ( $ctype->indeterminate ) {
56
- $direction = 'any';
57
- }
58
-
59
- $directions = array_intersect(
60
- _p2p_expand_direction( $show_ui ),
61
- _p2p_expand_direction( $direction )
62
- );
63
- }
64
-
65
- return $directions;
66
  }
67
 
68
  abstract function add_item( $directed, $object_type, $post_type, $title );
24
 
25
  $directions = self::determine_directions( $ctype, $object_type, $post_type, $args->show );
26
 
27
+ $title = self::get_title( $directions, $ctype );
 
 
 
 
 
28
 
29
  foreach ( $directions as $direction ) {
30
  $key = ( 'to' == $direction ) ? 'to' : 'from';
36
  }
37
  }
38
 
39
+ protected static function get_title( $directions, $ctype ) {
40
+ $title = array(
41
+ 'from' => $ctype->get_field( 'title', 'from' ),
42
+ 'to' => $ctype->get_field( 'title', 'to' )
43
+ );
44
+
45
+ if ( count( $directions ) > 1 && $title['from'] == $title['to'] ) {
46
+ $title['from'] .= __( ' (from)', P2P_TEXTDOMAIN );
47
+ $title['to'] .= __( ' (to)', P2P_TEXTDOMAIN );
48
+ }
49
+
50
+ return $title;
51
+ }
52
+
53
  protected static function determine_directions( $ctype, $object_type, $post_type, $show_ui ) {
54
  $direction = $ctype->direction_from_types( $object_type, $post_type );
55
  if ( !$direction )
56
  return array();
57
 
58
+ return $ctype->_directions_for_admin( $direction, $show_ui );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
 
61
  abstract function add_item( $directed, $object_type, $post_type, $title );
admin/images/delete.png DELETED
Binary file
admin/images/minus.png ADDED
Binary file
admin/images/{add.png → plus.png} RENAMED
File without changes
admin/templates/connection-types-form.html CHANGED
@@ -5,4 +5,4 @@
5
  <option>{{.}}</option>
6
  {{/options}}
7
  </select>
8
- <input class="button" type="submit" name="p2p_convert" value="{{{button_text}}}" />
5
  <option>{{.}}</option>
6
  {{/options}}
7
  </select>
8
+ <input class="button button-small" type="submit" name="p2p_convert" value="{{{button_text}}}" />
command.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ WP_CLI::add_command( 'p2p', 'P2P_CLI_Command' );
4
+
5
+ class P2P_CLI_Command extends WP_CLI_Command {
6
+
7
+ /**
8
+ * List registered connection types.
9
+ *
10
+ * @subcommand connection-types
11
+ */
12
+ function connection_types() {
13
+ foreach ( P2P_Connection_Type_Factory::get_all_instances() as $p2p_type => $ctype ) {
14
+ WP_CLI::line( $p2p_type );
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Generate connections for a specific connection type.
20
+ *
21
+ * @subcommand generate-connections
22
+ * @synopsis <connection-type> [--items]
23
+ */
24
+ function generate_connections( $args, $assoc_args ) {
25
+ list( $connection_type ) = $args;
26
+
27
+ $ctype = p2p_type( $connection_type );
28
+ if ( !$ctype )
29
+ WP_CLI::error( "'$connection_type' is not a registered connection type." );
30
+
31
+ if ( isset( $assoc_args['items'] ) ) {
32
+ foreach ( _p2p_extract_post_types( $ctype->side ) as $ptype ) {
33
+ $command = array( 'wp', 'post', 'generate' );
34
+ $assoc_args = array( 'post_type' => $ptype );
35
+
36
+ WP_CLI::launch( WP_CLI::compose_args( $command, $assoc_args ) );
37
+ }
38
+ }
39
+
40
+ $count = $this->_generate_c( $ctype );
41
+
42
+ WP_CLI::success( "Created $count connections." );
43
+ }
44
+
45
+ private function _generate_c( $ctype ) {
46
+ $extra_qv = array( 'p2p:per_page' => 10 );
47
+
48
+ $candidate = $ctype
49
+ ->set_direction( 'from' )
50
+ ->get_connectable( 'any', $extra_qv, 'abstract' );
51
+
52
+ $count = 0;
53
+
54
+ foreach ( $candidate->items as $from ) {
55
+ $eligible = $ctype->get_connectable( $from, array(
56
+ 'p2p:per_page' => rand( 0, 5 )
57
+ ), 'abstract' );
58
+
59
+ foreach ( $eligible->items as $to ) {
60
+ $r = $ctype->connect( $from, $to );
61
+
62
+ if ( is_wp_error( $r ) )
63
+ WP_CLI::warning( $r );
64
+ else
65
+ $count++;
66
+ }
67
+ }
68
+
69
+ return $count;
70
+ }
71
+
72
+ /**
73
+ * Set up the example connections.
74
+ *
75
+ * @subcommand setup-example
76
+ */
77
+ function setup_example() {
78
+ $ctype = p2p_type( 'actor_movie' );
79
+
80
+ $data = array(
81
+ 'Nicholas Cage' => array( 'Lord Of War', 'Adaptation' ),
82
+ 'Jude Law' => array( 'Sherlock Holmes' ),
83
+ 'Brad Pitt' => array( '7 Years In Tibet', 'Fight Club' ),
84
+ 'Natalie Portman' => array( 'Black Swan', 'Thor' ),
85
+ 'Matt Damon' => array( 'The Talented Mr. Ripley' ),
86
+ 'Charlize Theron' => array(),
87
+ );
88
+
89
+ foreach ( $data as $actor_name => $movies ) {
90
+ $actor = self::titled_post( 'actor', $actor_name );
91
+
92
+ foreach ( $movies as $movie_title ) {
93
+ $movie = self::titled_post( 'movie', $movie_title );
94
+
95
+ $ctype->connect( $actor, $movie );
96
+ }
97
+ }
98
+
99
+ WP_CLI::success( "Set up the actors and movies example." );
100
+ }
101
+
102
+ private static function titled_post( $type, $title ) {
103
+ return wp_insert_post( array(
104
+ 'post_type' => $type,
105
+ 'post_title' => $title,
106
+ 'post_status' => 'publish'
107
+ ) );
108
+ }
109
+ }
110
+
core/api.php CHANGED
@@ -77,7 +77,11 @@ function p2p_register_connection_type( $args ) {
77
  $args['admin_box']['context'] = _p2p_pluck( $args, 'context' );
78
  }
79
 
80
- return P2P_Connection_Type_Factory::register( $args );
 
 
 
 
81
  }
82
 
83
  /**
@@ -321,6 +325,9 @@ function p2p_list_posts( $posts, $args = array() ) {
321
  if ( is_a( $posts, 'P2P_List' ) ) {
322
  $list = $posts;
323
  } else {
 
 
 
324
  $list = new P2P_List( $posts, 'P2P_Item_Post' );
325
  }
326
 
77
  $args['admin_box']['context'] = _p2p_pluck( $args, 'context' );
78
  }
79
 
80
+ $ctype = P2P_Connection_Type_Factory::register( $args );
81
+
82
+ do_action( 'p2p_registered_connection_type', $ctype, $args );
83
+
84
+ return $ctype;
85
  }
86
 
87
  /**
325
  if ( is_a( $posts, 'P2P_List' ) ) {
326
  $list = $posts;
327
  } else {
328
+ if ( is_a( $posts, 'WP_Query' ) )
329
+ $posts = $posts->posts;
330
+
331
  $list = new P2P_List( $posts, 'P2P_Item_Post' );
332
  }
333
 
core/directed-type.php CHANGED
@@ -34,27 +34,21 @@ class P2P_Directed_Connection_Type {
34
  return $this->set_direction( _p2p_flip_direction( $this->direction ) );
35
  }
36
 
37
- public function get( $side, $key ) {
38
- switch ( $side ) {
39
- case 'current':
40
- $map = array(
41
  'to' => 'to',
42
  'from' => 'from',
43
  'any' => 'from'
44
- );
45
- break;
46
- case 'opposite':
47
- $map = array(
48
  'to' => 'from',
49
  'from' => 'to',
50
  'any' => 'to'
51
- );
52
- break;
53
- }
54
-
55
- $arg = $this->ctype->$key;
56
 
57
- return $arg[ $map[ $this->direction ] ];
58
  }
59
 
60
  private function abstract_query( $qv, $which, $output = 'abstract' ) {
@@ -69,6 +63,16 @@ class P2P_Directed_Connection_Type {
69
  return $side->get_list( $query );
70
  }
71
 
 
 
 
 
 
 
 
 
 
 
72
  protected function recognize( $item, $which = 'current' ) {
73
  return $this->get( $which, 'side' )->item_recognize( $item );
74
  }
@@ -137,7 +141,7 @@ class P2P_Directed_Connection_Type {
137
  public function get_connectable( $arg, $extra_qv = array(), $output = 'raw' ) {
138
  $side = $this->get( 'opposite', 'side' );
139
 
140
- $item = $this->recognize( $arg );
141
 
142
  $extra_qv['p2p:exclude'] = $this->get_non_connectable( $item, $extra_qv );
143
 
@@ -158,6 +162,8 @@ class P2P_Directed_Connection_Type {
158
  }
159
 
160
  $extra_qv['fields'] = 'ids';
 
 
161
  $already_connected = $this->get_connected( $to_check, $extra_qv, 'abstract' )->items;
162
 
163
  _p2p_append( $to_exclude, $already_connected );
@@ -165,22 +171,6 @@ class P2P_Directed_Connection_Type {
165
  return $to_exclude;
166
  }
167
 
168
- private function _check_params( $from_arg, $to_arg ) {
169
- $from = $this->recognize( $from_arg, 'current' );
170
- if ( !$from )
171
- return new WP_Error( 'first_parameter', 'Invalid first parameter.' );
172
-
173
- if ( 'any' == $to_arg ) {
174
- $to = 'any';
175
- } else {
176
- $to = $this->recognize( $to_arg, 'opposite' );
177
- if ( !$to )
178
- return new WP_Error( 'second_parameter', 'Invalid second parameter.' );
179
- }
180
-
181
- return compact( 'from', 'to' );
182
- }
183
-
184
  /**
185
  * Connect two items.
186
  *
@@ -190,12 +180,14 @@ class P2P_Directed_Connection_Type {
190
  *
191
  * @return int|object p2p_id or WP_Error on failure
192
  */
193
- public function connect( $from, $to, $meta = array() ) {
194
- $r = $this->_check_params( $from, $to );
195
- if ( is_wp_error( $r ) )
196
- return $r;
197
 
198
- extract( $r );
 
 
199
 
200
  if ( !$this->self_connections && $from->get_id() == $to->get_id() )
201
  return new WP_Error( 'self_connection', 'Connection between an element and itself is not allowed.' );
@@ -240,7 +232,7 @@ class P2P_Directed_Connection_Type {
240
 
241
  protected function get_default( $args, $p2p_id ) {
242
  if ( isset( $args['default_cb'] ) )
243
- return call_user_func( $args['default_cb'], p2p_get_connection( $p2p_id ) );
244
 
245
  if ( !isset( $args['default'] ) )
246
  return null;
@@ -256,12 +248,16 @@ class P2P_Directed_Connection_Type {
256
  *
257
  * @return int|object count or WP_Error on failure
258
  */
259
- public function disconnect( $from, $to ) {
260
- $r = $this->_check_params( $from, $to );
261
- if ( is_wp_error( $r ) )
262
- return $r;
 
 
 
 
263
 
264
- return $this->delete_connections( $r );
265
  }
266
 
267
  public function get_p2p_id( $from, $to ) {
@@ -275,10 +271,17 @@ class P2P_Directed_Connection_Type {
275
  /**
276
  * Transforms $this->get_connections( ... ) into p2p_get_connections( $this->name, ... ) etc.
277
  */
278
- public function __call( $method, $args ) {
279
- $args[0]['direction'] = $this->direction;
 
 
 
 
 
 
 
280
 
281
- return call_user_func( 'p2p_' . $method, $this->name, $args[0] );
282
  }
283
  }
284
 
34
  return $this->set_direction( _p2p_flip_direction( $this->direction ) );
35
  }
36
 
37
+ public function get( $side, $field ) {
38
+ static $map = array(
39
+ 'current' => array(
 
40
  'to' => 'to',
41
  'from' => 'from',
42
  'any' => 'from'
43
+ ),
44
+ 'opposite' => array(
 
 
45
  'to' => 'from',
46
  'from' => 'to',
47
  'any' => 'to'
48
+ )
49
+ );
 
 
 
50
 
51
+ return $this->ctype->get_field( $field, $map[ $side ][ $this->direction ] );
52
  }
53
 
54
  private function abstract_query( $qv, $which, $output = 'abstract' ) {
63
  return $side->get_list( $query );
64
  }
65
 
66
+ protected function recognize_any( $item, $which = 'current' ) {
67
+ if ( 'any' == $item )
68
+ return new P2P_Item_Any;
69
+
70
+ if ( is_a( $item, 'P2P_Item_Any' ) )
71
+ return $item;
72
+
73
+ return $this->recognize( $item, $which );
74
+ }
75
+
76
  protected function recognize( $item, $which = 'current' ) {
77
  return $this->get( $which, 'side' )->item_recognize( $item );
78
  }
141
  public function get_connectable( $arg, $extra_qv = array(), $output = 'raw' ) {
142
  $side = $this->get( 'opposite', 'side' );
143
 
144
+ $item = $this->recognize_any( $arg );
145
 
146
  $extra_qv['p2p:exclude'] = $this->get_non_connectable( $item, $extra_qv );
147
 
162
  }
163
 
164
  $extra_qv['fields'] = 'ids';
165
+ $extra_qv['p2p:per_page'] = -1;
166
+
167
  $already_connected = $this->get_connected( $to_check, $extra_qv, 'abstract' )->items;
168
 
169
  _p2p_append( $to_exclude, $already_connected );
171
  return $to_exclude;
172
  }
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  /**
175
  * Connect two items.
176
  *
180
  *
181
  * @return int|object p2p_id or WP_Error on failure
182
  */
183
+ public function connect( $from_arg, $to_arg, $meta = array() ) {
184
+ $from = $this->recognize( $from_arg, 'current' );
185
+ if ( !$from )
186
+ return new WP_Error( 'first_parameter', 'Invalid first parameter.' );
187
 
188
+ $to = $this->recognize( $to_arg, 'opposite' );
189
+ if ( !$to )
190
+ return new WP_Error( 'second_parameter', 'Invalid second parameter.' );
191
 
192
  if ( !$this->self_connections && $from->get_id() == $to->get_id() )
193
  return new WP_Error( 'self_connection', 'Connection between an element and itself is not allowed.' );
232
 
233
  protected function get_default( $args, $p2p_id ) {
234
  if ( isset( $args['default_cb'] ) )
235
+ return call_user_func( $args['default_cb'], p2p_get_connection( $p2p_id ), $this->direction );
236
 
237
  if ( !isset( $args['default'] ) )
238
  return null;
248
  *
249
  * @return int|object count or WP_Error on failure
250
  */
251
+ public function disconnect( $from_arg, $to_arg ) {
252
+ $from = $this->recognize( $from_arg, 'current' );
253
+ if ( !$from )
254
+ return new WP_Error( 'first_parameter', 'Invalid first parameter.' );
255
+
256
+ $to = $this->recognize_any( $to_arg, 'opposite' );
257
+ if ( !$to )
258
+ return new WP_Error( 'second_parameter', 'Invalid second parameter.' );
259
 
260
+ return $this->delete_connections( compact( 'from', 'to' ) );
261
  }
262
 
263
  public function get_p2p_id( $from, $to ) {
271
  /**
272
  * Transforms $this->get_connections( ... ) into p2p_get_connections( $this->name, ... ) etc.
273
  */
274
+ public function __call( $method, $argv ) {
275
+ list( $args ) = $argv;
276
+
277
+ $args['direction'] = $this->direction;
278
+
279
+ foreach ( array( 'from', 'to' ) as $key ) {
280
+ if ( isset( $args[ $key ] ) && is_a( $args[ $key ], 'P2P_Item_Any' ) )
281
+ $args[ $key ] = 'any';
282
+ }
283
 
284
+ return call_user_func( 'p2p_' . $method, $this->name, $args );
285
  }
286
  }
287
 
core/extra.php CHANGED
@@ -141,18 +141,31 @@ function _p2p_get_list( $args ) {
141
 
142
  $connected = $directed->$method( $item, $extra_qv, 'abstract' );
143
 
144
- $args = array(
145
- 'before_list' => '<ul id="' . $ctype->name . '_list">',
146
- 'echo' => false
147
- );
 
 
148
 
149
- if ( 'ol' == $mode ) {
150
- _p2p_append( $args, array(
151
  'before_list' => '<ol id="' . $ctype->name . '_list">',
152
  'after_list' => '</ol>',
153
- ) );
 
 
 
 
 
 
 
 
 
154
  }
155
 
 
 
156
  return apply_filters( "p2p_{$context}_html", $connected->render( $args ), $connected, $directed, $mode );
157
  }
158
 
141
 
142
  $connected = $directed->$method( $item, $extra_qv, 'abstract' );
143
 
144
+ switch ( $mode ) {
145
+ case 'inline':
146
+ $args = array(
147
+ 'separator' => ', '
148
+ );
149
+ break;
150
 
151
+ case 'ol':
152
+ $args = array(
153
  'before_list' => '<ol id="' . $ctype->name . '_list">',
154
  'after_list' => '</ol>',
155
+ );
156
+ break;
157
+
158
+ case 'ul':
159
+ default:
160
+ $args = array(
161
+ 'before_list' => '<ul id="' . $ctype->name . '_list">',
162
+ 'after_list' => '</ul>',
163
+ );
164
+ break;
165
  }
166
 
167
+ $args['echo'] = false;
168
+
169
  return apply_filters( "p2p_{$context}_html", $connected->render( $args ), $connected, $directed, $mode );
170
  }
171
 
core/indeterminate-type.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- class P2P_Indeterminate_Connection_Type extends P2P_Directed_Connection_Type {
4
 
5
  protected function recognize( $arg ) {
6
  foreach ( array( 'current', 'opposite' ) as $side ) {
@@ -23,8 +23,12 @@ class P2P_Indeterminate_Connection_Type extends P2P_Directed_Connection_Type {
23
  $other_qv = $this->get( 'opposite', 'side' )->get_base_qv( $q );
24
 
25
  // need to be inclusive
26
- if ( isset( $other_qv['post_type'] ) )
27
- _p2p_append( $args['post_type'], $other_qv['post_type'] );
 
 
 
 
28
 
29
  return $args;
30
  }
1
  <?php
2
 
3
+ class P2P_Indeterminate_Directed_Connection_Type extends P2P_Directed_Connection_Type {
4
 
5
  protected function recognize( $arg ) {
6
  foreach ( array( 'current', 'opposite' ) as $side ) {
23
  $other_qv = $this->get( 'opposite', 'side' )->get_base_qv( $q );
24
 
25
  // need to be inclusive
26
+ if ( isset( $other_qv['post_type'] ) ) {
27
+ $args['post_type'] = array_unique( array_merge(
28
+ (array) $args['post_type'],
29
+ (array) $other_qv['post_type']
30
+ ) );
31
+ }
32
 
33
  return $args;
34
  }
core/item.php CHANGED
@@ -33,6 +33,24 @@ abstract class P2P_Item {
33
  }
34
 
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  class P2P_Item_Post extends P2P_Item {
37
 
38
  function get_title() {
33
  }
34
 
35
 
36
+ class P2P_Item_Any extends P2P_Item {
37
+
38
+ function __construct() {}
39
+
40
+ function get_permalink() {}
41
+
42
+ function get_title() {}
43
+
44
+ function get_object() {
45
+ return 'any';
46
+ }
47
+
48
+ function get_id() {
49
+ return false;
50
+ }
51
+ }
52
+
53
+
54
  class P2P_Item_Post extends P2P_Item {
55
 
56
  function get_title() {
core/list.php CHANGED
@@ -44,7 +44,7 @@ class P2P_List {
44
  if ( $separator ) {
45
  $list = array();
46
  foreach ( $this->items as $item ) {
47
- $list[] = $this->render_item( $item->get_object() );
48
  }
49
  echo implode( $separator, $list );
50
  } else {
44
  if ( $separator ) {
45
  $list = array();
46
  foreach ( $this->items as $item ) {
47
+ $list[] = $this->render_item( $item );
48
  }
49
  echo implode( $separator, $list );
50
  } else {
core/query.php CHANGED
@@ -199,7 +199,7 @@ class P2P_Query {
199
  if ( $this->order_num )
200
  $field .= '+0';
201
 
202
- $clauses['orderby'] = "p2pm_order.$field $order";
203
  }
204
 
205
  return $clauses;
199
  if ( $this->order_num )
200
  $field .= '+0';
201
 
202
+ $clauses['orderby'] = "p2pm_order.$field $order, " . str_replace( 'ORDER BY ', '', $clauses['orderby'] );
203
  }
204
 
205
  return $clauses;
core/side.php CHANGED
@@ -2,6 +2,10 @@
2
 
3
  abstract class P2P_Side {
4
 
 
 
 
 
5
  abstract function get_title();
6
  abstract function get_desc();
7
  abstract function get_labels();
@@ -12,21 +16,28 @@ abstract class P2P_Side {
12
  abstract function get_base_qv( $q );
13
  abstract function translate_qv( $qv );
14
  abstract function do_query( $args );
15
- abstract function get_list( $query );
16
  abstract function capture_query( $args );
 
17
 
18
  abstract function is_indeterminate( $side );
19
 
20
- protected $item_type;
 
 
21
 
 
 
 
22
  function item_recognize( $arg ) {
23
  $class = $this->item_type;
24
 
25
- if ( is_a( $arg, $class ) )
26
- return $arg;
 
 
27
 
28
- if ( is_a( $arg, 'P2P_Item' ) )
29
- return false;
30
 
31
  $raw_item = $this->recognize( $arg );
32
  if ( !$raw_item )
@@ -34,6 +45,11 @@ abstract class P2P_Side {
34
 
35
  return new $class( $raw_item );
36
  }
 
 
 
 
 
37
  }
38
 
39
 
@@ -45,6 +61,10 @@ class P2P_Side_Post extends P2P_Side {
45
  $this->query_vars = $query_vars;
46
  }
47
 
 
 
 
 
48
  public function first_post_type() {
49
  return $this->query_vars['post_type'][0];
50
  }
@@ -81,7 +101,7 @@ class P2P_Side_Post extends P2P_Side {
81
  }
82
 
83
  function get_labels() {
84
- return get_object_vars( $this->get_ptype()->labels );
85
  }
86
 
87
  function can_edit_connections() {
@@ -98,17 +118,24 @@ class P2P_Side_Post extends P2P_Side {
98
  return true;
99
  }
100
 
101
- function do_query( $args ) {
102
- return new WP_Query( $args );
103
- }
 
 
 
 
 
104
 
105
- function get_list( $wp_query ) {
106
- $list = new P2P_List( $wp_query->posts, $this->item_type );
 
107
 
108
- $list->current_page = max( 1, $wp_query->get('paged') );
109
- $list->total_pages = $wp_query->max_num_pages;
110
 
111
- return $list;
 
112
  }
113
 
114
  function capture_query( $args ) {
@@ -120,20 +147,13 @@ class P2P_Side_Post extends P2P_Side {
120
  return $q->_p2p_sql;
121
  }
122
 
123
- function translate_qv( $qv ) {
124
- $map = array(
125
- 'include' => 'post__in',
126
- 'exclude' => 'post__not_in',
127
- 'search' => 's',
128
- 'page' => 'paged',
129
- 'per_page' => 'posts_per_page'
130
- );
131
 
132
- foreach ( $map as $old => $new )
133
- if ( isset( $qv["p2p:$old"] ) )
134
- $qv[$new] = _p2p_pluck( $qv, "p2p:$old" );
135
 
136
- return $qv;
137
  }
138
 
139
  function is_indeterminate( $side ) {
@@ -145,27 +165,10 @@ class P2P_Side_Post extends P2P_Side {
145
  return !empty( $common );
146
  }
147
 
148
- function item_recognize( $arg ) {
149
- $class = $this->item_type;
150
-
151
- if ( is_a( $arg, $class ) ) {
152
- if ( !$this->recognize_post_type( $arg->post_type ) )
153
- return false;
154
-
155
- return $arg;
156
- }
157
-
158
- if ( is_a( $arg, 'P2P_Item' ) )
159
- return false;
160
-
161
- $raw_item = $this->recognize( $arg );
162
- if ( !$raw_item )
163
  return false;
164
 
165
- return new $class( $raw_item );
166
- }
167
-
168
- protected function recognize( $arg ) {
169
  $post = get_post( $arg );
170
 
171
  if ( !is_object( $post ) )
@@ -216,6 +219,10 @@ class P2P_Side_User extends P2P_Side {
216
  $this->query_vars = $query_vars;
217
  }
218
 
 
 
 
 
219
  function get_desc() {
220
  return __( 'Users', P2P_TEXTDOMAIN );
221
  }
@@ -225,7 +232,7 @@ class P2P_Side_User extends P2P_Side {
225
  }
226
 
227
  function get_labels() {
228
- return array(
229
  'singular_name' => __( 'User', P2P_TEXTDOMAIN ),
230
  'search_items' => __( 'Search Users', P2P_TEXTDOMAIN ),
231
  'not_found' => __( 'No users found.', P2P_TEXTDOMAIN ),
@@ -240,22 +247,28 @@ class P2P_Side_User extends P2P_Side {
240
  return false;
241
  }
242
 
243
- function do_query( $args ) {
244
- return new WP_User_Query( $args );
245
- }
246
 
247
- function get_list( $query ) {
248
- $list = new P2P_List( $query->get_results(), $this->item_type );
249
 
250
- $qv = $query->query_vars;
 
251
 
252
- if ( isset( $qv['p2p:page'] ) ) {
253
- $list->current_page = $qv['p2p:page'];
254
- $list->total_pages = ceil( $query->get_total() / $qv['p2p:per_page'] );
255
  }
256
 
257
- return $list;
258
  }
 
 
 
 
 
259
  function capture_query( $args ) {
260
  $args['count_total'] = false;
261
 
@@ -287,22 +300,17 @@ class P2P_Side_User extends P2P_Side {
287
  return "SELECT $uq->query_fields $uq->query_from $uq->query_where $uq->query_orderby $uq->query_limit";
288
  }
289
 
290
- function translate_qv( $qv ) {
291
- if ( isset( $qv['p2p:include'] ) )
292
- $qv['include'] = _p2p_pluck( $qv, 'p2p:include' );
293
-
294
- if ( isset( $qv['p2p:exclude'] ) )
295
- $qv['exclude'] = _p2p_pluck( $qv, 'p2p:exclude' );
296
 
297
- if ( isset( $qv['p2p:search'] ) && $qv['p2p:search'] )
298
- $qv['search'] = '*' . _p2p_pluck( $qv, 'p2p:search' ) . '*';
299
 
300
- if ( isset( $qv['p2p:page'] ) && $qv['p2p:page'] > 0 ) {
301
- $qv['number'] = $qv['p2p:per_page'];
302
- $qv['offset'] = $qv['p2p:per_page'] * ( $qv['p2p:page'] - 1 );
303
  }
304
 
305
- return $qv;
306
  }
307
 
308
  function is_indeterminate( $side ) {
2
 
3
  abstract class P2P_Side {
4
 
5
+ protected $item_type;
6
+
7
+ abstract function get_object_type();
8
+
9
  abstract function get_title();
10
  abstract function get_desc();
11
  abstract function get_labels();
16
  abstract function get_base_qv( $q );
17
  abstract function translate_qv( $qv );
18
  abstract function do_query( $args );
 
19
  abstract function capture_query( $args );
20
+ abstract function get_list( $query );
21
 
22
  abstract function is_indeterminate( $side );
23
 
24
+ final function is_same_type( $side ) {
25
+ return $this->get_object_type() == $side->get_object_type();
26
+ }
27
 
28
+ /**
29
+ * @param object Raw object or P2P_Item
30
+ */
31
  function item_recognize( $arg ) {
32
  $class = $this->item_type;
33
 
34
+ if ( is_a( $arg, 'P2P_Item' ) ) {
35
+ if ( !is_a( $arg, $class ) ) {
36
+ return false;
37
+ }
38
 
39
+ $arg = $arg->get_object();
40
+ }
41
 
42
  $raw_item = $this->recognize( $arg );
43
  if ( !$raw_item )
45
 
46
  return new $class( $raw_item );
47
  }
48
+
49
+ /**
50
+ * @param object Raw object
51
+ */
52
+ abstract protected function recognize( $arg );
53
  }
54
 
55
 
61
  $this->query_vars = $query_vars;
62
  }
63
 
64
+ public function get_object_type() {
65
+ return 'post';
66
+ }
67
+
68
  public function first_post_type() {
69
  return $this->query_vars['post_type'][0];
70
  }
101
  }
102
 
103
  function get_labels() {
104
+ return $this->get_ptype()->labels;
105
  }
106
 
107
  function can_edit_connections() {
118
  return true;
119
  }
120
 
121
+ function translate_qv( $qv ) {
122
+ $map = array(
123
+ 'include' => 'post__in',
124
+ 'exclude' => 'post__not_in',
125
+ 'search' => 's',
126
+ 'page' => 'paged',
127
+ 'per_page' => 'posts_per_page'
128
+ );
129
 
130
+ foreach ( $map as $old => $new )
131
+ if ( isset( $qv["p2p:$old"] ) )
132
+ $qv[$new] = _p2p_pluck( $qv, "p2p:$old" );
133
 
134
+ return $qv;
135
+ }
136
 
137
+ function do_query( $args ) {
138
+ return new WP_Query( $args );
139
  }
140
 
141
  function capture_query( $args ) {
147
  return $q->_p2p_sql;
148
  }
149
 
150
+ function get_list( $wp_query ) {
151
+ $list = new P2P_List( $wp_query->posts, $this->item_type );
 
 
 
 
 
 
152
 
153
+ $list->current_page = max( 1, $wp_query->get('paged') );
154
+ $list->total_pages = $wp_query->max_num_pages;
 
155
 
156
+ return $list;
157
  }
158
 
159
  function is_indeterminate( $side ) {
165
  return !empty( $common );
166
  }
167
 
168
+ protected function recognize( $arg ) {
169
+ if ( is_object( $arg ) && !isset( $arg->post_type ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  return false;
171
 
 
 
 
 
172
  $post = get_post( $arg );
173
 
174
  if ( !is_object( $post ) )
219
  $this->query_vars = $query_vars;
220
  }
221
 
222
+ function get_object_type() {
223
+ return 'user';
224
+ }
225
+
226
  function get_desc() {
227
  return __( 'Users', P2P_TEXTDOMAIN );
228
  }
232
  }
233
 
234
  function get_labels() {
235
+ return (object) array(
236
  'singular_name' => __( 'User', P2P_TEXTDOMAIN ),
237
  'search_items' => __( 'Search Users', P2P_TEXTDOMAIN ),
238
  'not_found' => __( 'No users found.', P2P_TEXTDOMAIN ),
247
  return false;
248
  }
249
 
250
+ function translate_qv( $qv ) {
251
+ if ( isset( $qv['p2p:include'] ) )
252
+ $qv['include'] = _p2p_pluck( $qv, 'p2p:include' );
253
 
254
+ if ( isset( $qv['p2p:exclude'] ) )
255
+ $qv['exclude'] = _p2p_pluck( $qv, 'p2p:exclude' );
256
 
257
+ if ( isset( $qv['p2p:search'] ) && $qv['p2p:search'] )
258
+ $qv['search'] = '*' . _p2p_pluck( $qv, 'p2p:search' ) . '*';
259
 
260
+ if ( isset( $qv['p2p:page'] ) && $qv['p2p:page'] > 0 ) {
261
+ $qv['number'] = $qv['p2p:per_page'];
262
+ $qv['offset'] = $qv['p2p:per_page'] * ( $qv['p2p:page'] - 1 );
263
  }
264
 
265
+ return $qv;
266
  }
267
+
268
+ function do_query( $args ) {
269
+ return new WP_User_Query( $args );
270
+ }
271
+
272
  function capture_query( $args ) {
273
  $args['count_total'] = false;
274
 
300
  return "SELECT $uq->query_fields $uq->query_from $uq->query_where $uq->query_orderby $uq->query_limit";
301
  }
302
 
303
+ function get_list( $query ) {
304
+ $list = new P2P_List( $query->get_results(), $this->item_type );
 
 
 
 
305
 
306
+ $qv = $query->query_vars;
 
307
 
308
+ if ( isset( $qv['p2p:page'] ) ) {
309
+ $list->current_page = $qv['p2p:page'];
310
+ $list->total_pages = ceil( $query->get_total() / $qv['p2p:per_page'] );
311
  }
312
 
313
+ return $list;
314
  }
315
 
316
  function is_indeterminate( $side ) {
core/storage.php CHANGED
@@ -50,7 +50,7 @@ class P2P_Storage {
50
 
51
  foreach ( P2P_Connection_Type_Factory::get_all_instances() as $p2p_type => $ctype ) {
52
  foreach ( array( 'from', 'to' ) as $direction ) {
53
- if ( $object_type == $ctype->object[ $direction ] ) {
54
  p2p_delete_connections( $p2p_type, array(
55
  $direction => $object_id,
56
  ) );
50
 
51
  foreach ( P2P_Connection_Type_Factory::get_all_instances() as $p2p_type => $ctype ) {
52
  foreach ( array( 'from', 'to' ) as $direction ) {
53
+ if ( $object_type == $ctype->side[ $direction ]->get_object_type() ) {
54
  p2p_delete_connections( $p2p_type, array(
55
  $direction => $object_id,
56
  ) );
core/type-factory.php CHANGED
@@ -5,16 +5,7 @@ class P2P_Connection_Type_Factory {
5
  private static $instances = array();
6
 
7
  public static function register( $args ) {
8
- if ( isset( $args['name'] ) ) {
9
- if ( strlen( $args['name'] ) > 44 ) {
10
- trigger_error( sprintf( "Connection name '%s' is longer than 44 characters.", $args['name'] ), E_USER_WARNING );
11
- return false;
12
- }
13
- } else {
14
- trigger_error( "Connection types without a 'name' parameter are deprecated.", E_USER_WARNING );
15
- }
16
-
17
- $args = wp_parse_args( $args, array(
18
  'name' => false,
19
  'from_object' => 'post',
20
  'to_object' => 'post',
@@ -32,44 +23,81 @@ class P2P_Connection_Type_Factory {
32
  'from_labels' => '',
33
  'to_labels' => '',
34
  'reciprocal' => false,
35
- ) );
36
 
37
- $sides = array();
38
 
39
- foreach ( array( 'from', 'to' ) as $direction ) {
40
- $object = _p2p_pluck( $args, $direction );
 
 
41
 
42
- if ( 'user' == $object )
43
- $args[ $direction . '_object' ] = 'user';
44
- elseif ( 'attachment' == $object )
45
- $args[ $direction . '_object' ] = 'attachment';
46
 
47
- if ( 'post' == $args[ $direction . '_object' ] ) {
48
- $args[ $direction . '_query_vars' ]['post_type'] = (array) $object;
49
- }
50
  }
51
 
52
  if ( !$args['name'] ) {
53
- $args['name'] = md5( serialize( array_values( wp_array_slice_assoc( $args, array(
54
- 'from_object', 'to_object',
55
- 'from_query_vars', 'to_query_vars',
56
- 'data'
57
- ) ) ) ) );
58
  }
59
 
60
- $args = apply_filters( 'p2p_connection_type_args', $args );
61
 
62
- $ctype = new P2P_Connection_Type( $args );
63
 
64
- if ( isset( self::$instances[ $ctype->name ] ) ) {
65
- trigger_error( "Connection type '$ctype->name' is already defined.", E_USER_NOTICE );
66
- }
67
 
68
  self::$instances[ $ctype->name ] = $ctype;
69
 
70
  return $ctype;
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  public static function get_all_instances() {
74
  return self::$instances;
75
  }
5
  private static $instances = array();
6
 
7
  public static function register( $args ) {
8
+ $defaults = array(
 
 
 
 
 
 
 
 
 
9
  'name' => false,
10
  'from_object' => 'post',
11
  'to_object' => 'post',
23
  'from_labels' => '',
24
  'to_labels' => '',
25
  'reciprocal' => false,
26
+ );
27
 
28
+ $args = shortcode_atts( $defaults, $args );
29
 
30
+ if ( strlen( $args['name'] ) > 44 ) {
31
+ trigger_error( sprintf( "Connection name '%s' is longer than 44 characters.", $args['name'] ), E_USER_WARNING );
32
+ return false;
33
+ }
34
 
35
+ $sides = array();
 
 
 
36
 
37
+ foreach ( array( 'from', 'to' ) as $direction ) {
38
+ $sides[ $direction ] = self::create_side( $args, $direction );
 
39
  }
40
 
41
  if ( !$args['name'] ) {
42
+ trigger_error( "Connection types without a 'name' parameter are deprecated.", E_USER_WARNING );
43
+ $args['name'] = self::generate_name( $sides, $args );
 
 
 
44
  }
45
 
46
+ $args = apply_filters( 'p2p_connection_type_args', $args, $sides );
47
 
48
+ $class = self::get_ctype_class( $sides, _p2p_pluck( $args, 'reciprocal' ) );
49
 
50
+ $ctype = new $class( $args, $sides );
 
 
51
 
52
  self::$instances[ $ctype->name ] = $ctype;
53
 
54
  return $ctype;
55
  }
56
 
57
+ private static function create_side( &$args, $direction ) {
58
+ $object = _p2p_pluck( $args, $direction );
59
+
60
+ if ( in_array( $object, array( 'user', 'attachment' ) ) )
61
+ $object_type = $object;
62
+ else
63
+ $object_type = 'post';
64
+
65
+ $query_vars = _p2p_pluck( $args, $direction . '_query_vars' );
66
+
67
+ if ( 'post' == $object_type )
68
+ $query_vars['post_type'] = (array) $object;
69
+
70
+ $class = 'P2P_Side_' . ucfirst( $object_type );
71
+
72
+ return new $class( $query_vars );
73
+ }
74
+
75
+ private static function generate_name( $sides, $args ) {
76
+ $vals = array(
77
+ $sides['from']->get_object_type(),
78
+ $sides['to']->get_object_type(),
79
+ $sides['from']->query_vars,
80
+ $sides['to']->query_vars,
81
+ $args['data']
82
+ );
83
+
84
+ return md5( serialize( $vals ) );
85
+ }
86
+
87
+ private static function get_ctype_class( $sides, $reciprocal ) {
88
+ if ( $sides['from']->is_same_type( $sides['to'] ) &&
89
+ $sides['from']->is_indeterminate( $sides['to'] ) ) {
90
+ if ( $reciprocal )
91
+ $class = 'P2P_Reciprocal_Connection_Type';
92
+ else
93
+ $class = 'P2P_Indeterminate_Connection_Type';
94
+ } else {
95
+ $class = 'P2P_Connection_Type';
96
+ }
97
+
98
+ return $class;
99
+ }
100
+
101
  public static function get_all_instances() {
102
  return self::$instances;
103
  }
core/type.php CHANGED
@@ -2,38 +2,31 @@
2
 
3
  class P2P_Connection_Type {
4
 
5
- public $indeterminate;
6
 
7
- public $object;
8
 
9
  public $side;
10
 
11
  public $cardinality;
12
 
13
- public $title;
14
-
15
  public $labels;
16
 
17
- public function __construct( $args ) {
18
- foreach ( array( 'from', 'to' ) as $direction ) {
19
- $this->object[ $direction ] = _p2p_pluck( $args, $direction . '_object' );
20
 
21
- $class = 'P2P_Side_' . ucfirst( $this->object[ $direction ] );
 
22
 
23
- $this->side[ $direction ] = new $class( _p2p_pluck( $args, $direction . '_query_vars' ) );
24
- }
25
-
26
- if ( $this->object['from'] == $this->object['to'] ) {
27
- $this->indeterminate = $this->side['from']->is_indeterminate( $this->side['to'] );
28
- } else {
29
- $args['self_connections'] = true;
30
- }
31
 
32
  $this->set_cardinality( _p2p_pluck( $args, 'cardinality' ) );
33
 
34
- $this->set_labels( $args );
 
 
 
35
 
36
- $this->title = $this->expand_title( _p2p_pluck( $args, 'title' ) );
37
 
38
  $this->fields = $this->expand_fields( _p2p_pluck( $args, 'fields' ) );
39
 
@@ -42,6 +35,37 @@ class P2P_Connection_Type {
42
  }
43
  }
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  private function expand_fields( $fields ) {
46
  foreach ( $fields as &$field_args )
47
  {
@@ -73,38 +97,30 @@ class P2P_Connection_Type {
73
  }
74
  }
75
 
76
- private function set_labels( &$args ) {
77
- foreach ( array( 'from', 'to' ) as $key ) {
78
- $labels = $this->side[ $key ]->get_labels();
79
- $labels['create'] = __( 'Create connections', P2P_TEXTDOMAIN );
80
 
81
- _p2p_append( $labels, (array) _p2p_pluck( $args, $key . '_labels' ) );
82
 
83
- $this->labels[ $key ] = (object) $labels;
84
- }
 
 
85
  }
86
 
87
- private function expand_title( $title ) {
88
- if ( $title && !is_array( $title ) ) {
89
- return array(
90
- 'from' => $title,
91
- 'to' => $title,
92
- );
93
- }
94
 
95
- foreach ( array( 'from', 'to' ) as $key ) {
96
- if ( isset( $title[$key] ) )
97
- continue;
98
 
99
- $other_key = ( 'from' == $key ) ? 'to' : 'from';
100
 
101
- $title[$key] = sprintf(
102
- __( 'Connected %s', P2P_TEXTDOMAIN ),
103
- $this->side[ $other_key ]->get_title()
104
- );
105
- }
106
-
107
- return $title;
108
  }
109
 
110
  public function __call( $method, $args ) {
@@ -135,7 +151,7 @@ class P2P_Connection_Type {
135
  return false;
136
 
137
  if ( $instantiate ) {
138
- $class = $this->indeterminate ? 'P2P_Indeterminate_Connection_Type' : 'P2P_Directed_Connection_Type';
139
 
140
  return new $class( $this, $direction );
141
  }
@@ -173,25 +189,26 @@ class P2P_Connection_Type {
173
  return false;
174
  }
175
 
176
- public function direction_from_item( $arg ) {
 
 
 
 
177
  foreach ( array( 'from', 'to' ) as $direction ) {
178
  $item = $this->side[ $direction ]->item_recognize( $arg );
179
 
180
  if ( !$item )
181
  continue;
182
 
183
- if ( $this->indeterminate )
184
- $direction = $this->reciprocal ? 'any' : 'from';
185
-
186
- return $direction;
187
  }
188
 
189
  return false;
190
  }
191
 
192
- public function direction_from_object_type( $current ) {
193
- $from = $this->object['from'];
194
- $to = $this->object['to'];
195
 
196
  if ( $from == $to && $current == $from )
197
  return 'any';
@@ -210,17 +227,14 @@ class P2P_Connection_Type {
210
  if ( !$this->_type_check( $direction, $object_type, $post_types ) )
211
  continue;
212
 
213
- if ( $this->indeterminate )
214
- $direction = $this->reciprocal ? 'any' : 'from';
215
-
216
- return $direction;
217
  }
218
 
219
  return false;
220
  }
221
 
222
  private function _type_check( $direction, $object_type, $post_types ) {
223
- if ( $object_type != $this->object[ $direction ] )
224
  return false;
225
 
226
  $side = $this->side[ $direction ];
@@ -330,9 +344,11 @@ class P2P_Connection_Type {
330
  $possible_directions = array();
331
 
332
  foreach ( array( 'from', 'to' ) as $direction ) {
333
- if ( 'post' == $this->object[$direction] ) {
 
 
334
  foreach ( $post_types as $post_type ) {
335
- if ( $this->side[ $direction ]->recognize_post_type( $post_type ) ) {
336
  $possible_directions[] = $direction;
337
  }
338
  }
@@ -368,11 +384,9 @@ class P2P_Connection_Type {
368
  $$key = $this->side[ $key ]->get_desc();
369
  }
370
 
371
- $arrow = $this->indeterminate ? '&harr;' : '&rarr;';
372
-
373
- $label = "$from $arrow $to";
374
 
375
- $title = $this->title[ 'from' ];
376
 
377
  if ( $title )
378
  $label .= " ($title)";
@@ -381,3 +395,36 @@ class P2P_Connection_Type {
381
  }
382
  }
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  class P2P_Connection_Type {
4
 
5
+ protected $directed_class = 'P2P_Directed_Connection_Type';
6
 
7
+ protected $arrow = '&rarr;';
8
 
9
  public $side;
10
 
11
  public $cardinality;
12
 
 
 
13
  public $labels;
14
 
15
+ protected $title;
 
 
16
 
17
+ public function __construct( $args, $sides ) {
18
+ $this->side = $sides;
19
 
20
+ $this->set_self_connections( $args );
 
 
 
 
 
 
 
21
 
22
  $this->set_cardinality( _p2p_pluck( $args, 'cardinality' ) );
23
 
24
+ $labels = array();
25
+ foreach ( array( 'from', 'to' ) as $key ) {
26
+ $labels[ $key ] = (array) _p2p_pluck( $args, $key . '_labels' );
27
+ }
28
 
29
+ $this->labels = $labels;
30
 
31
  $this->fields = $this->expand_fields( _p2p_pluck( $args, 'fields' ) );
32
 
35
  }
36
  }
37
 
38
+ public function get_field( $field, $direction ) {
39
+ $value = $this->$field;
40
+
41
+ if ( 'title' == $field )
42
+ return $this->expand_title( $value, $direction );
43
+
44
+ if ( 'labels' == $field )
45
+ return $this->expand_labels( $value, $direction );
46
+
47
+ if ( false === $direction )
48
+ return $value;
49
+
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'];
63
+
64
+ if ( !$from_side->is_same_type( $to_side ) ) {
65
+ $args['self_connections'] = true;
66
+ }
67
+ }
68
+
69
  private function expand_fields( $fields ) {
70
  foreach ( $fields as &$field_args )
71
  {
97
  }
98
  }
99
 
100
+ private function expand_labels( $additional_labels, $key ) {
101
+ $additional_labels['create'] = __( 'Create connections', P2P_TEXTDOMAIN );
 
 
102
 
103
+ $labels = clone $this->side[ $key ]->get_labels();
104
 
105
+ foreach ( $additional_labels as $key => $var )
106
+ $labels->$key = $var;
107
+
108
+ return $labels;
109
  }
110
 
111
+ private function expand_title( $title, $key ) {
112
+ if ( $title && !is_array( $title ) )
113
+ return $title;
 
 
 
 
114
 
115
+ if ( isset( $title[$key] ) )
116
+ return $title[$key];
 
117
 
118
+ $other_key = ( 'from' == $key ) ? 'to' : 'from';
119
 
120
+ return sprintf(
121
+ __( 'Connected %s', P2P_TEXTDOMAIN ),
122
+ $this->side[ $other_key ]->get_title()
123
+ );
 
 
 
124
  }
125
 
126
  public function __call( $method, $args ) {
151
  return false;
152
 
153
  if ( $instantiate ) {
154
+ $class = $this->directed_class;
155
 
156
  return new $class( $this, $direction );
157
  }
189
  return false;
190
  }
191
 
192
+ protected function choose_direction( $direction ) {
193
+ return $direction;
194
+ }
195
+
196
+ protected function direction_from_item( $arg ) {
197
  foreach ( array( 'from', 'to' ) as $direction ) {
198
  $item = $this->side[ $direction ]->item_recognize( $arg );
199
 
200
  if ( !$item )
201
  continue;
202
 
203
+ return $this->choose_direction( $direction );
 
 
 
204
  }
205
 
206
  return false;
207
  }
208
 
209
+ protected function direction_from_object_type( $current ) {
210
+ $from = $this->side['from']->get_object_type();
211
+ $to = $this->side['to']->get_object_type();
212
 
213
  if ( $from == $to && $current == $from )
214
  return 'any';
227
  if ( !$this->_type_check( $direction, $object_type, $post_types ) )
228
  continue;
229
 
230
+ return $this->choose_direction( $direction );
 
 
 
231
  }
232
 
233
  return false;
234
  }
235
 
236
  private function _type_check( $direction, $object_type, $post_types ) {
237
+ if ( $object_type != $this->side[ $direction ]->get_object_type() )
238
  return false;
239
 
240
  $side = $this->side[ $direction ];
344
  $possible_directions = array();
345
 
346
  foreach ( array( 'from', 'to' ) as $direction ) {
347
+ $side = $this->side[ $direction ];
348
+
349
+ if ( 'post' == $side->get_object_type() ) {
350
  foreach ( $post_types as $post_type ) {
351
+ if ( $side->recognize_post_type( $post_type ) ) {
352
  $possible_directions[] = $direction;
353
  }
354
  }
384
  $$key = $this->side[ $key ]->get_desc();
385
  }
386
 
387
+ $label = "$from {$this->arrow} $to";
 
 
388
 
389
+ $title = $this->get_field( 'title', 'from' );
390
 
391
  if ( $title )
392
  $label .= " ($title)";
395
  }
396
  }
397
 
398
+
399
+ class P2P_Indeterminate_Connection_Type extends P2P_Connection_Type {
400
+
401
+ protected $directed_class = 'P2P_Indeterminate_Directed_Connection_Type';
402
+
403
+ protected $arrow = '&harr;';
404
+
405
+ protected function choose_direction( $direction ) {
406
+ return 'from';
407
+ }
408
+
409
+ function _directions_for_admin( $direction, $show_ui ) {
410
+ return parent::_directions_for_admin( 'any', $show_ui );
411
+ }
412
+ }
413
+
414
+
415
+ class P2P_Reciprocal_Connection_Type extends P2P_Indeterminate_Connection_Type {
416
+
417
+ protected function choose_direction( $direction ) {
418
+ return 'any';
419
+ }
420
+
421
+ function _directions_for_admin( $direction, $show_ui ) {
422
+ if ( $show_ui )
423
+ $directions = array( 'any' );
424
+ else
425
+ $directions = array();
426
+
427
+ return $directions;
428
+ }
429
+ }
430
+
core/url-query.php CHANGED
@@ -36,7 +36,7 @@ class P2P_URL_Query {
36
  return;
37
 
38
  _p2p_append( $query->query_vars, wp_array_slice_assoc( $_GET,
39
- P2P_URL_Query::get_custom_qv() ) );
40
  }
41
  }
42
 
36
  return;
37
 
38
  _p2p_append( $query->query_vars, wp_array_slice_assoc( $_GET,
39
+ self::get_custom_qv() ) );
40
  }
41
  }
42
 
core/util.php CHANGED
@@ -2,6 +2,9 @@
2
 
3
  /** @internal */
4
  function _p2p_expand_direction( $direction ) {
 
 
 
5
  if ( 'any' == $direction )
6
  return array( 'from', 'to' );
7
  else
@@ -54,6 +57,18 @@ function _p2p_wrap( $items, $class ) {
54
  return $items;
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  /** @internal */
58
  function _p2p_meta_sql_helper( $query ) {
59
  global $wpdb;
2
 
3
  /** @internal */
4
  function _p2p_expand_direction( $direction ) {
5
+ if ( !$direction )
6
+ return array();
7
+
8
  if ( 'any' == $direction )
9
  return array( 'from', 'to' );
10
  else
57
  return $items;
58
  }
59
 
60
+ /** @internal */
61
+ function _p2p_extract_post_types( $sides ) {
62
+ $ptypes = array();
63
+
64
+ foreach ( $sides as $side ) {
65
+ if ( 'post' == $side->get_object_type() )
66
+ _p2p_append( $ptypes, $side->query_vars['post_type'] );
67
+ }
68
+
69
+ return array_unique( $ptypes );
70
+ }
71
+
72
  /** @internal */
73
  function _p2p_meta_sql_helper( $query ) {
74
  global $wpdb;
debug-utils.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Tools for testing and debugging P2P
4
+
5
+ add_action( 'p2p_registered_connection_type', '_p2p_register_missing_post_types' );
6
+
7
+ function _p2p_register_missing_post_types( $ctype ) {
8
+ foreach ( _p2p_extract_post_types( $ctype->side ) as $ptype ) {
9
+ if ( !post_type_exists( $ptype ) ) {
10
+ _p2p_generate_post_type( $ptype );
11
+ }
12
+ }
13
+ }
14
+
15
+ function _p2p_generate_post_type( $slug ) {
16
+ register_post_type( $slug, array(
17
+ 'labels' => array(
18
+ 'name' => ucfirst( $slug ),
19
+ 'singular_name' => ucfirst( $slug ),
20
+ ),
21
+ 'public' => true,
22
+ 'supports' => array( 'title' )
23
+ ) );
24
+ }
25
+
26
+ function _p2p_walk( $posts, $level = 0 ) {
27
+ if ( 0 == $level )
28
+ echo "<pre>\n";
29
+
30
+ foreach ( $posts as $post ) {
31
+ echo str_repeat( "\t", $level ) . "$post->ID: $post->post_title\n";
32
+
33
+ if ( isset( $post->connected ) )
34
+ _p2p_walk( $post->connected, $level+1 );
35
+ }
36
+
37
+ if ( 0 == $level )
38
+ echo "</pre>\n";
39
+ }
40
+
lang/posts-to-posts-nl_NL.mo CHANGED
Binary file
lang/posts-to-posts-nl_NL.po CHANGED
@@ -1,18 +1,59 @@
1
- # Translation of 1.4.1 in Dutch
2
- # This file is distributed under the same license as the 1.4.1 package.
3
  msgid ""
4
  msgstr ""
5
- "PO-Revision-Date: 2012-09-07 15:36+0100\n"
6
  "MIME-Version: 1.0\n"
7
  "Content-Type: text/plain; charset=UTF-8\n"
8
  "Content-Transfer-Encoding: 8bit\n"
9
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
10
- "X-Generator: GlotPress/0.1\n"
11
- "Project-Id-Version: 1.4.1\n"
12
  "POT-Creation-Date: \n"
13
  "Last-Translator: Remco Tolsma <remco@pronamic.nl>\n"
14
  "Language-Team: \n"
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  #: admin/box.php:38
17
  msgid "Are you sure you want to delete all connections?"
18
  msgstr "Weet je zeker dat je alle verbindingen wilt verwijderen?"
@@ -33,10 +74,6 @@ msgstr "volgende"
33
  msgid "of"
34
  msgstr "of"
35
 
36
- #: admin/box.php:236
37
- msgid "Can't create connection: %s"
38
- msgstr "Kan verbinding niet maken: %s"
39
-
40
  #: admin/factory.php:30
41
  msgid " (from)"
42
  msgstr "(van)"
@@ -53,46 +90,29 @@ msgstr "Verwijder alle verbindingen"
53
  msgid "Delete connection"
54
  msgstr "Verwijder verbinding"
55
 
56
- #: admin/tools.php:7
57
- msgid "Connection Types"
58
- msgstr "Verbindingstypen"
59
-
60
- #: admin/tools.php:41
61
- msgid "<em>%s</em> is not a registered connection type."
62
- msgstr "<em>%s</em> is niet een geregistreerde verbindingstype."
63
-
64
- #: admin/tools.php:50
65
- msgid "Converted %1$s connections from <em>%2$s</em> to <em>%3$s</em>."
66
- msgstr "%1$s verbindingen omgezet van <em>%2$s</em> naar <em>%3$s</em>."
67
-
68
- #: admin/tools.php:64
69
- msgid "Name"
70
- msgstr "Naam"
71
-
72
- #: admin/tools.php:65
73
- msgid "Information"
74
- msgstr "Informatie"
75
 
76
- #: admin/tools.php:66
77
- msgid "Connections"
78
- msgstr "Verbindingen"
79
 
80
- #: admin/tools.php:74
81
- msgid "No connection types registered."
82
- msgstr "Geen verbindingstypen geregistreerd."
83
 
84
- #: admin/tools.php:76
85
- msgid "To register a connection type, see <a href=\"%s\">the wiki</a>."
86
- msgstr ""
87
- "Bekijk <a href=\"%s\">de wiki</a> om een verbindingstype te registeren."
88
 
89
- #: admin/tools.php:93
90
- msgid "Convert to registered connection type:"
91
- msgstr "Omzetten naar geregistreerde verbindingstype:"
92
 
93
- #: admin/tools.php:129
94
- msgid "Go"
95
- msgstr "Go"
96
 
97
  #: core/extra.php:16
98
  msgid "Posts 2 Posts"
@@ -112,7 +132,7 @@ msgstr "Verbindingstype:"
112
 
113
  #: core/extra.php:46
114
  msgid "Connection listing:"
115
- msgstr "Verbinding lijst:"
116
 
117
  #: core/extra.php:52
118
  msgid "connected"
@@ -122,30 +142,6 @@ msgstr "verbonden"
122
  msgid "related"
123
  msgstr "gerelateerd"
124
 
125
- #: core/side.php:220
126
- msgid "Users"
127
- msgstr "Gebruikers"
128
-
129
- #: core/side.php:229
130
- msgid "User"
131
- msgstr "Gebruiker"
132
-
133
- #: core/side.php:230
134
- msgid "Search Users"
135
- msgstr "Gebruikers zoeken"
136
-
137
- #: core/side.php:231
138
- msgid "No users found."
139
- msgstr "Geen gebruikers gevonden."
140
-
141
- #: core/type.php:79
142
- msgid "Create connections"
143
- msgstr "Verbindingen maken"
144
-
145
- #: core/type.php:102
146
- msgid "Connected %s"
147
- msgstr "Verbonden %s"
148
-
149
  #: scb/AdminPage.php:172
150
  msgid "Settings <strong>saved</strong>."
151
  msgstr "Instellingen <strong>opgeslagen</strong>."
1
+ # Translation of 1.4.3-alpha in Dutch
2
+ # This file is distributed under the same license as the 1.4.3-alpha package.
3
  msgid ""
4
  msgstr ""
5
+ "PO-Revision-Date: 2012-09-19 09:35+0100\n"
6
  "MIME-Version: 1.0\n"
7
  "Content-Type: text/plain; charset=UTF-8\n"
8
  "Content-Transfer-Encoding: 8bit\n"
9
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
10
+ "X-Generator: Poedit 1.5.3\n"
11
+ "Project-Id-Version: 1.4.3-alpha\n"
12
  "POT-Creation-Date: \n"
13
  "Last-Translator: Remco Tolsma <remco@pronamic.nl>\n"
14
  "Language-Team: \n"
15
 
16
+ #: admin/tools.php:7
17
+ msgid "Connection Types"
18
+ msgstr "Verbindingstypen"
19
+
20
+ #: admin/tools.php:41
21
+ msgid "<em>%s</em> is not a registered connection type."
22
+ msgstr "<em>%s</em> is niet een geregistreerde verbindingstype."
23
+
24
+ #: admin/tools.php:50
25
+ msgid "Converted %1$s connections from <em>%2$s</em> to <em>%3$s</em>."
26
+ msgstr "%1$s verbindingen omgezet van <em>%2$s</em> naar <em>%3$s</em>."
27
+
28
+ #: admin/tools.php:64
29
+ msgid "Name"
30
+ msgstr "Naam"
31
+
32
+ #: admin/tools.php:65
33
+ msgid "Information"
34
+ msgstr "Informatie"
35
+
36
+ #: admin/tools.php:66
37
+ msgid "Connections"
38
+ msgstr "Verbindingen"
39
+
40
+ #: admin/tools.php:74
41
+ msgid "No connection types registered."
42
+ msgstr "Geen verbindingstypen geregistreerd."
43
+
44
+ #: admin/tools.php:76
45
+ msgid "To register a connection type, see <a href=\"%s\">the wiki</a>."
46
+ msgstr ""
47
+ "Bekijk <a href=\"%s\">de wiki</a> om een verbindingstype te registeren."
48
+
49
+ #: admin/tools.php:93
50
+ msgid "Convert to registered connection type:"
51
+ msgstr "Omzetten naar geregistreerde verbindingstype:"
52
+
53
+ #: admin/tools.php:129
54
+ msgid "Go"
55
+ msgstr "Ga"
56
+
57
  #: admin/box.php:38
58
  msgid "Are you sure you want to delete all connections?"
59
  msgstr "Weet je zeker dat je alle verbindingen wilt verwijderen?"
74
  msgid "of"
75
  msgstr "of"
76
 
 
 
 
 
77
  #: admin/factory.php:30
78
  msgid " (from)"
79
  msgstr "(van)"
90
  msgid "Delete connection"
91
  msgstr "Verwijder verbinding"
92
 
93
+ #: core/type.php:85
94
+ msgid "Create connections"
95
+ msgstr "Verbindingen maken"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ #: core/type.php:108
98
+ msgid "Connected %s"
99
+ msgstr "Verbonden %s"
100
 
101
+ #: core/side.php:224
102
+ msgid "Users"
103
+ msgstr "Gebruikers"
104
 
105
+ #: core/side.php:233
106
+ msgid "User"
107
+ msgstr "Gebruiker"
 
108
 
109
+ #: core/side.php:234
110
+ msgid "Search Users"
111
+ msgstr "Gebruikers zoeken"
112
 
113
+ #: core/side.php:235
114
+ msgid "No users found."
115
+ msgstr "Geen gebruikers gevonden."
116
 
117
  #: core/extra.php:16
118
  msgid "Posts 2 Posts"
132
 
133
  #: core/extra.php:46
134
  msgid "Connection listing:"
135
+ msgstr "Verbindingslijst:"
136
 
137
  #: core/extra.php:52
138
  msgid "connected"
142
  msgid "related"
143
  msgstr "gerelateerd"
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  #: scb/AdminPage.php:172
146
  msgid "Settings <strong>saved</strong>."
147
  msgstr "Instellingen <strong>opgeslagen</strong>."
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.4.2
6
  Author: scribu
7
  Author URI: http://scribu.net/
8
  Plugin URI: http://scribu.net/wordpress/posts-to-posts
@@ -10,7 +10,7 @@ Text Domain: posts-to-posts
10
  Domain Path: /lang
11
  */
12
 
13
- define( 'P2P_PLUGIN_VERSION', '1.4' );
14
 
15
  define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
16
 
2
  /*
3
  Plugin Name: Posts 2 Posts
4
  Description: Create many-to-many relationships between all types of posts.
5
+ Version: 1.4.3
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.4.3' );
14
 
15
  define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
16
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: scribu, ciobi
3
  Tags: connections, custom post types, relationships, many-to-many, users
4
  Requires at least: 3.4
5
- Tested up to: 3.4
6
- Stable tag: 1.4.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -31,7 +31,7 @@ Links: [**Documentation**](http://github.com/scribu/wp-posts-to-posts/wiki) | [P
31
  See [Installing Plugins](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins).
32
 
33
  After activating it, refer to the [Basic usage](https://github.com/scribu/wp-posts-to-posts/wiki/Basic-usage) tutorial.
34
-
35
  Additional info can be found on the [wiki](http://github.com/scribu/wp-posts-to-posts/wiki).
36
 
37
  == Frequently Asked Questions ==
@@ -53,6 +53,12 @@ Make sure your host is running PHP 5. The only foolproof way to do this is to ad
53
 
54
  == Changelog ==
55
 
 
 
 
 
 
 
56
  = 1.4.2 =
57
  * fixed each_connected() returning wrapped objects
58
  * fixed issue with user queries and get_current_screen()
2
  Contributors: scribu, ciobi
3
  Tags: connections, custom post types, relationships, many-to-many, users
4
  Requires at least: 3.4
5
+ Tested up to: 3.5
6
+ Stable tag: 1.4.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
31
  See [Installing Plugins](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins).
32
 
33
  After activating it, refer to the [Basic usage](https://github.com/scribu/wp-posts-to-posts/wiki/Basic-usage) tutorial.
34
+
35
  Additional info can be found on the [wiki](http://github.com/scribu/wp-posts-to-posts/wiki).
36
 
37
  == Frequently Asked Questions ==
53
 
54
  == Changelog ==
55
 
56
+ = 1.4.3 =
57
+ * various bug fixes
58
+ * added 'inline' mode for shortcodes
59
+ * replaced 'trash' icon with 'minus' icon
60
+ * pass direction to 'default_cb'
61
+
62
  = 1.4.2 =
63
  * fixed each_connected() returning wrapped objects
64
  * fixed issue with user queries and get_current_screen()
screenshot-1.png DELETED
Binary file
screenshot-2.png DELETED
Binary file
screenshot-3.png DELETED
Binary file
screenshot-4.png DELETED
Binary file
screenshot-5.png DELETED
Binary file