Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fet/rest relation endpoints (fixes #790) #798

Merged
merged 34 commits into from
Dec 30, 2018
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7973911
add routes for adding and removing relations
Nov 22, 2018
0b5c0aa
add validateModel method for reduring duplicated code in child classes
Nov 26, 2018
8269c41
use validateModel to make code more DRY
Nov 26, 2018
393bb89
theoretically, rest relation updating endpoints have been added. Unte…
Nov 26, 2018
2b8284a
first test and a few fixes
Nov 27, 2018
c6656fa
relation adding and removing endpoints are unit tested
Nov 27, 2018
a12d2bc
phpcbf fixes
Nov 27, 2018
447b197
Merge branch 'master' into FET/rest-relation-endpoints
Nov 27, 2018
9252e45
import classes during unit tests
Nov 27, 2018
8444d86
ModelDataTranslator::prepareFieldvalueForJson doesnt need the timezon…
Nov 27, 2018
48c5e9c
import more classes
Nov 27, 2018
624d839
if they provide invalid parameters have an error, just like when inse…
Nov 27, 2018
9f848b8
deletion is successful if no row was found
Nov 28, 2018
2409adc
update test expectations
Nov 28, 2018
64bde44
update documentation to mention new relation editing endpoints
Nov 28, 2018
f5e3dbf
added item to REST API changelog
Nov 28, 2018
a43aa97
ouops all these tests should remove relations so be named like that
Nov 28, 2018
4238659
removing relations does not accept any parameters. These endpoints as…
Nov 28, 2018
979df92
assert that we remove ALL relations when removing relations not just one
Nov 28, 2018
d8d0b52
consider join table entries as duplicates based only on foreign keys
Nov 28, 2018
d7e9186
update tests to make sure we update relations instead of adding dupli…
Nov 28, 2018
6f12835
update tests to make sure we update relations instead of adding dupli…
Nov 28, 2018
18214e9
phpcbf fix
Nov 28, 2018
67101a4
update documentation
Nov 28, 2018
adb4004
Merge branch 'master' into FET/rest-relation-endpoints
Nov 30, 2018
5344486
remove the unnecessary success property and document it
Nov 30, 2018
485d93d
Merge branch 'master' into FET/rest-relation-endpoints
Nov 30, 2018
d1e153b
Merge branch 'master' into FET/rest-relation-endpoints
Dec 4, 2018
02db8d7
fix fatal error when running tests on phpunit4.8
Dec 5, 2018
7aa00fd
Merge branch 'master' into FET/rest-relation-endpoints
Dec 13, 2018
ac5cb47
fixed some documentation typos as brent suggested
Dec 13, 2018
77afa00
Merge branch 'master' into FET/rest-relation-endpoints
Dec 17, 2018
00c747a
Merge branch 'master' into FET/rest-relation-endpoints
Dec 27, 2018
9adf8b6
Merge branch 'master' into FET/rest-relation-endpoints
nerrad Dec 30, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/db_classes/EE_Base_Class.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -2329,8 +2329,8 @@ public function _add_relation_to(
* You can optionally include an array of key=>value pairs that allow you to further constrict the
* relation to being added. However, keep in mind that the columns (keys) given must match a column
* on the JOIN table and currently only the HABTM models accept these additional conditions. Also
* remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
* created in the join table.
* remember that if an exact match isn't found for these extra cols/val pairs, then no row is
* deleted.
* @return EE_Base_Class the relation was removed from
* @throws ReflectionException
* @throws InvalidArgumentException
Expand Down
59 changes: 49 additions & 10 deletions core/db_models/relations/EE_HABTM_Relation.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public function add_relation_to($this_obj_or_id, $other_obj_or_id, $extra_join_m
$join_model_fk_to_this_model = $this->get_join_model()->get_foreign_key_to($this->get_this_model()->get_this_model_name());
$join_model_fk_to_other_model = $this->get_join_model()->get_foreign_key_to($this->get_other_model()->get_this_model_name());

$cols_n_values = array(
$foreign_keys = $all_fields = array(
$join_model_fk_to_this_model->get_name() => $this_model_obj->ID(),
$join_model_fk_to_other_model->get_name() => $other_model_obj->ID(),
);
Expand All @@ -173,18 +173,21 @@ public function add_relation_to($this_obj_or_id, $other_obj_or_id, $extra_join_m
);
$parsed_query[ $query_param ] = $val;
}
$cols_n_values = array_merge($cols_n_values, $parsed_query);
$all_fields = array_merge($foreign_keys, $parsed_query);
}

$query_params = array($cols_n_values);


$existing_entry_in_join_table = $this->get_join_model()->get_one($query_params);
// if there is already an entry in the join table, indicating a relationship, we're done
// again, if you want more sophisticated logic or insertions (handling more columns than just 2 foreign keys to
// the other tables, use the joining model directly!
$existing_entry_in_join_table = $this->get_join_model()->get_one(array($foreign_keys));
// If there is already an entry in the join table, indicating a relationship, update it instead of adding a
// new row.
// Again, if you want more sophisticated logic or insertions (handling more columns than just 2 foreign keys to
// the other tables) use the joining model directly!
if (! $existing_entry_in_join_table) {
$this->get_join_model()->insert($cols_n_values);
$this->get_join_model()->insert($all_fields);
} else {
$this->get_join_model()->update(
$all_fields,
array($foreign_keys)
);
}
return $other_model_obj;
}
Expand Down Expand Up @@ -232,4 +235,40 @@ public function remove_relation_to($this_obj_or_id, $other_obj_or_id, $where_que
$this->get_join_model()->delete(array($cols_n_values));
return $other_model_obj;
}

/**
* Gets all the non-key fields (ie, not the primary key and not foreign keys) on the join model.
* @since $VID:$
* @return EE_Model_Field_Base[]
* @throws EE_Error
*/
public function getNonKeyFields()
{
// all fields besides the primary key and two foreign keys should be parameters
$join_model = $this->get_join_model();
$standard_fields = array();
if ($join_model->has_primary_key_field()) {
$standard_fields[] = $join_model->primary_key_name();
}
if ($this->get_this_model()->has_primary_key_field()) {
$standard_fields[] = $this->get_this_model()->primary_key_name();
}
if ($this->get_other_model()->has_primary_key_field()) {
$standard_fields[] = $this->get_other_model()->primary_key_name();
}
return array_diff_key(
$join_model->field_settings(),
array_flip($standard_fields)
);
}

/**
* Returns true if the join model has non-key fields (ie, fields that aren't the primary key or foreign keys.)
* @since $VID:$
* @return boolean
*/
public function hasNonKeyFields()
{
return count($this->get_join_model()->field_settings()) > 3;
}
}
28 changes: 28 additions & 0 deletions core/libraries/rest_api/controllers/model/Base.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php
namespace EventEspresso\core\libraries\rest_api\controllers\model;

use EEM_Base;
use EventEspresso\core\libraries\rest_api\controllers\Base as Controller_Base;
use EventEspresso\core\libraries\rest_api\ModelVersionInfo;
use EE_Error;
use EventEspresso\core\libraries\rest_api\RestException;

/**
* Base
Expand Down Expand Up @@ -80,5 +82,31 @@ public function isSubclassOfOne($object, $classnames)
}
return false;
}

/**
* Verifies the model name provided was valid. If so, returns the model (as an object). Otherwise, throws an
* exception. Must be called after `setRequestedVersion()`.
* @since $VID:$
* @param $model_name
* @return EEM_Base
* @throws EE_Error
* @throws RestException
*/
protected function validateModel($model_name)
{
if (! $this->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
throw new RestException(
'endpoint_parsing_error',
sprintf(
__(
'There is no model for endpoint %s. Please contact event espresso support',
'event_espresso'
),
$model_name
)
);
}
return $this->getModelVersionInfo()->loadModel($model_name);
}
}
// End of file Base.php
31 changes: 2 additions & 29 deletions core/libraries/rest_api/controllers/model/Read.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,35 +301,8 @@ public static function handleRequestGetRelated(
$controller = LoaderFactory::getLoader()->getNew('EventEspresso\core\libraries\rest_api\controllers\model\Read');
try {
$controller->setRequestedVersion($version);
if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($model_name)) {
return $controller->sendResponse(
new WP_Error(
'endpoint_parsing_error',
sprintf(
__(
'There is no model for endpoint %s. Please contact event espresso support',
'event_espresso'
),
$model_name
)
)
);
}
$main_model = $controller->getModelVersionInfo()->loadModel($model_name);
if (! $controller->getModelVersionInfo()->isModelNameInThisVersion($related_model_name)) {
return $controller->sendResponse(
new WP_Error(
'endpoint_parsing_error',
sprintf(
__(
'There is no model for endpoint %s. Please contact event espresso support',
'event_espresso'
),
$related_model_name
)
)
);
}
$main_model = $controller->validateModel($model_name);
$controller->validateModel($related_model_name);
return $controller->sendResponse(
$controller->getEntitiesFromRelation(
$request->get_param('id'),
Expand Down
Loading