Skip to content

Commit

Permalink
Tidying p2p connection logic
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmuswinter committed Sep 11, 2017
1 parent d8e6dc5 commit 55e975b
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 62 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "A plugin for WordPress that makes post types easier to manage",
"minimum-stability": "stable",
"license": "GPL-3.0",
"version": "2.1.0",
"version": "2.1.1",
"autoload": {
"psr-4": {
"Outlandish\\Wordpress\\Oowp\\": "src/"
Expand Down
94 changes: 65 additions & 29 deletions src/PostTypeManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ protected function registerPostType($className)
}

$this->postTypes[$className] = $postType;
$this->connections[$postType] = array();

do_action('oowp/post_type_registered', $postType, $className);
}
Expand Down Expand Up @@ -135,45 +134,45 @@ public function getPostTypes()
return array_values($this->postTypes);
}

/**
* Registers a new connection between two post types
* @param string $postType
* @param string $targetPostType
* @param array $parameters
* @return bool|object
*/
public function registerConnection($postType, $targetPostType, $parameters)
/**
* Registers a new connection between two post types
* @param string $postType
* @param string $targetPostType
* @param array $parameters
* @param string $connectionName
* @return bool|object
*/
public function registerConnection($postType, $targetPostType, $parameters, $connectionName = null)
{
if (!function_exists('p2p_register_connection_type')) {
return null;
}

if(!array_key_exists($postType, $this->connections)) {
$this->connections[$postType] = array();
}
if(!array_key_exists($targetPostType, $this->connections)) {
$this->connections[$targetPostType] = array();
}
if(in_array($targetPostType, $this->connections[$postType]) || in_array($postType, $this->connections[$targetPostType])) {
return false; //this connection has already been registered
}
$this->connections[$targetPostType][] = $postType;
$this->connections[$postType][] = $targetPostType;
if (!$connectionName) {
$connectionName = $this->generateConnectionName($postType, $targetPostType);
}

$types = array($targetPostType, $postType);
sort($types);
if (array_key_exists($connectionName, $this->connections)) {
return $this->connections[$connectionName]->connection;
}

$connection_name = $this->generateConnectionName($postType, $targetPostType);
$defaults = array(
'name' => $connection_name,
'from' => $types[0],
'to' => $types[1],
'name' => $connectionName,
'from' => $postType,
'to' => $targetPostType,
'cardinality' => 'many-to-many',
'reciprocal' => true
);

$parameters = wp_parse_args($parameters, $defaults);
return p2p_register_connection_type($parameters);
$connection = p2p_register_connection_type($parameters);

$this->connections[$connectionName] = (object) [
'parameters' => $parameters,
'connection' => $connection
];

return $connection;
}

/**
Expand All @@ -195,8 +194,45 @@ public function generateConnectionName($postType, $targetType)
* @param string $postType
* @return string[]
*/
public function getConnections($postType)
public function getConnectedPostTypes($postType)
{
return array_key_exists($postType, $this->connections) ? $this->connections[$postType] : array();
$types = [];
foreach ($this->connections as $connection) {
if ($connection->parameters['from'] === $postType) {
$types[] = $connection->parameters['to'];
}
if ($connection->parameters['to'] === $postType) {
$types[] = $connection->parameters['from'];
}
}
return array_unique($types);
}

/**
* Gets all of the connection names that go between (one of) $postTypeA and (one of) $postTypeB
* @param string|string[] $postTypeA
* @param string|string[] $postTypeB
* @return string[]
*/
public function getConnectionNames($postTypeA, $postTypeB)
{
$connectionNames = [];
if ($postTypeA && $postTypeB) {
if (!is_array($postTypeB)) {
$postTypeB = [$postTypeB];
}
if (!is_array($postTypeA)) {
$postTypeA = [$postTypeA];
}
foreach ($this->connections as $name => $connection) {
if (in_array($connection->parameters['from'], $postTypeA) && in_array($connection->parameters['to'], $postTypeB)) {
$connectionNames[] = $name;
}
if (in_array($connection->parameters['from'], $postTypeB) && in_array($connection->parameters['to'], $postTypeA)) {
$connectionNames[] = $name;
}
}
}
return array_unique($connectionNames);
}
}
75 changes: 43 additions & 32 deletions src/PostTypes/WordpressPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,17 @@ public function connectAll($posts) {
}
}

/**
* @param $post int|object|WordpressPost
* @param array $meta
*/
public function connect($post, $meta = array()) {
/**
* @param $post int|object|WordpressPost
* @param array $meta
* @param string $connectionName
*/
public function connect($post, $meta = array(), $connectionName = null) {
$post = WordpressPost::createWordpressPost($post);
if ($post) {
$connectionName = PostTypeManager::get()->generateConnectionName(self::postType(), $post->post_type);
if (!$connectionName) {
$connectionName = PostTypeManager::get()->generateConnectionName(self::postType(), $post->post_type);
}
/** @var \P2P_Directed_Connection_Type $connectionType */
$connectionType = p2p_type($connectionName);
if ($connectionType) {
Expand All @@ -227,14 +230,15 @@ public function connect($post, $meta = array()) {
}
}

/**
* @param $targetPostType string e.g. post, event - the type of post you want to connect to
* @param bool $single - just return the first/only post?
* @param array $queryArgs - augment or overwrite the default parameters for the WP_Query
* @param bool $hierarchical - if this is true the the function will return any post that is connected to this post *or any of its descendants*
* @return null|WordpressPost|OowpQuery
*/
public function connected($targetPostType, $single = false, $queryArgs = array(), $hierarchical = false)
/**
* @param string|string[] $targetPostType e.g. post, event - the type of connected post(s) you want
* @param bool $single - just return the first/only post?
* @param array $queryArgs - augment or overwrite the default parameters for the WP_Query
* @param bool $hierarchical - if this is true the the function will return any post that is connected to this post *or any of its descendants*
* @param string|string[] $connectionName If specified, only this connection name is used to find the connected posts (defaults to any/all connections to $targetPostType)
* @return null|OowpQuery|WordpressPost
*/
public function connected($targetPostType, $single = false, $queryArgs = array(), $hierarchical = false, $connectionName = null)
{
$toReturn = null;
if (function_exists('p2p_register_connection_type')) {
Expand All @@ -243,17 +247,23 @@ public function connected($targetPostType, $single = false, $queryArgs = array()
}
$manager = PostTypeManager::get();
$postType = self::postType();
$connection_name = array();
foreach ($targetPostType as $targetType) {
$connection_name[] = $manager->generateConnectionName($postType, $targetType);
}

if (!$connectionName) {
$connectionName = $manager->getConnectionNames($postType, $targetPostType);
} else if (!is_array($connectionName)) {
$connectionName = [$connectionName];
}

$defaults = array(
'connected_type' => $connection_name,
'post_type' => $targetPostType,
'connected_type' => $connectionName,
'post_type' => $targetPostType,
);

#todo optimisation: check to see if this post type is hierarchical first
// ignore $hierarchical = true if this post type is not hierarchical
if ($hierarchical && !self::isHierarchical($postType)) {
$hierarchical = false;
}

if ($hierarchical) {
$defaults['connected_items'] = array_merge($this->getDescendantIds(), array($this->ID));
} else {
Expand All @@ -263,8 +273,8 @@ public function connected($targetPostType, $single = false, $queryArgs = array()
// use the menu order if $hierarchical is true, or any of the target post types are hierarchical
$useMenuOrder = $hierarchical;
if (!$useMenuOrder) {
foreach ($targetPostType as $postType) {
if (self::isHierarchical($postType)) {
foreach ($targetPostType as $otherPostType) {
if (self::isHierarchical($otherPostType)) {
$useMenuOrder = true;
break;
}
Expand Down Expand Up @@ -558,7 +568,7 @@ public function childPostClassNames()
*/
public static function connectedPostTypes()
{
return PostTypeManager::get()->getConnections(self::postType());
return PostTypeManager::get()->getConnectedPostTypes(self::postType());
}

/**
Expand Down Expand Up @@ -867,15 +877,16 @@ static function getQueriedObject() {
return $ooQueriedObject;
}

/**
* @static Creates a p2p connection to another post type
* @param $targetPostType - the post_type of the post type you want to connect to
* @param array $parameters - these can overwrite the defaults. though if you change the name of the connection you'll need a custom getConnected aswell
* @return mixed
*/
static function registerConnection($targetPostType, $parameters = array())
/**
* @static Creates a p2p connection to another post type
* @param string $targetPostType The post_type of the post type you want to connect to
* @param array $parameters These can overwrite the defaults. Do not specify connection_name, use $connectionName instead
* @param string $connectionName
* @return mixed
*/
static function registerConnection($targetPostType, $parameters = array(), $connectionName = null)
{
return PostTypeManager::get()->registerConnection(self::postType(), $targetPostType, $parameters);
return PostTypeManager::get()->registerConnection(self::postType(), $targetPostType, $parameters, $connectionName);
}

/**
Expand Down

0 comments on commit 55e975b

Please sign in to comment.