public function testGetRelationships() { $contact = $this->contact('testAnyone'); $otherContact = $this->contact('testUser'); $account = $this->account('account1'); $contact1Relationships = count($contact->relationships->getRelationships()); $contact2Relationships = count($otherContact->relationships->getRelationships()); $accountRelationships = count($account->relationships->getRelationships()); $rel = new Relationships(); $rel->firstType = get_class($contact); $rel->firstId = $contact->id; $rel->secondType = get_class($otherContact); $rel->secondId = $otherContact->id; $rel->save(); $this->assertEquals($contact1Relationships + 1, count($contact->relationships->getRelationships(true))); $this->assertEquals($contact2Relationships + 1, count($otherContact->relationships->getRelationships(true))); $rel2 = new Relationships(); $rel2->firstType = get_class($contact); $rel2->firstId = $contact->id; $rel2->secondType = get_class($account); $rel2->secondId = $account->id; $rel2->save(); $this->assertEquals($contact1Relationships + 2, count($contact->relationships->getRelationships(true))); $this->assertEquals($contact2Relationships + 1, count($otherContact->relationships->getRelationships(true))); $this->assertEquals($accountRelationships + 1, count($account->relationships->getRelationships(true))); $rel->delete(); $rel2->delete(); // Verify that cache is preserved unless we manually refresh it $this->assertEquals($contact1Relationships + 2, count($contact->relationships->getRelationships())); $this->assertEquals($contact2Relationships + 1, count($otherContact->relationships->getRelationships())); $this->assertEquals($accountRelationships + 1, count($account->relationships->getRelationships())); $this->assertEquals($contact1Relationships, count($contact->relationships->getRelationships(true))); $this->assertEquals($contact2Relationships, count($otherContact->relationships->getRelationships(true))); $this->assertEquals($accountRelationships, count($account->relationships->getRelationships(true))); }
/** * Action for viewing or modifying relationships on a model. * * @param type $_class * @param type $_id * @param type $_relatedId */ public function actionRelationships($_class = null, $_id = null, $_relatedId = null) { $method = Yii::app()->request->requestType; $relationship = null; if ($_relatedId !== null) { $relationship = Relationships::model()->findByPk($_relatedId); if (!$relationship instanceof Relationships) { $this->send(404, "Relationship with id={$_relatedId} not found."); } // Check whether the relationship is actually attached to this model: if ($_class !== null && $_id !== null && $relationship->firstId != $this->model->id && $relationship->secondId != $this->model->id && $relationship->firstType != $_class && $relationship->secondType != $_class) { $this->response->httpHeader['Location'] = $this->createAbsoluteUrl('/api2/relationships', array('_class' => $relationship->firstType, '_id' => $relationship->firstId, '_relatedId' => $relationship->id)); $this->send(303, "Specified relationship does not correspond " . "to {$_class} record {$_id}."); } } switch ($method) { case 'GET': if ($relationship !== null) { // Get an individual relationship record. Also, include the // resource URL of the related model. $which = $relationship->firstId == $_id && $relationship->firstType == $_class ? 'second' : 'first'; $relId = $which . 'Id'; $relType = $which . 'Type'; $this->response->httpHeader['Location'] = $this->createAbsoluteUrl('/api2/model', array('_class' => $relationship->{$relType}, '_id' => $relationship->{$relId})); $this->responseBody = $relationship; } else { // Query relationships on a model. $criteria = null; if (!$relationship instanceof Relationships) { // Both ingoing and outgoing relationships. $from = new CDbCriteria(); $to = new CDbCriteria(); $from->compare('firstType', $_class); $from->compare('firstId', $_id); $to->compare('secondType', $_class); $to->compare('secondId', $_id); $criteria = new CDbCriteria(); $criteria->mergeWith($from, 'OR'); $criteria->mergeWith($to, 'OR'); } $this->responseBody = $this->getDataProvider('Relationships', $criteria)->getData(); } break; case 'PATCH': case 'POST': case 'PUT': if (!$relationship instanceof Relationships) { if ($method !== 'POST') { // Cannot PUT on a nonexistent model $this->send(405, "Method \"POST\" is required to create new relationships."); } $relationship = new Relationships(); } // Scenario kludge that adds special validation rule for the // Relations model class, which dicates that it must point to // an existing record on both ends: $relationship->setScenario('api'); $relationship->setAttributes($this->jpost); // Set missing attributes, if any: if (empty($relationship->firstType)) { $relationship->firstType = $_class; $relationship->firstId = $_id; } elseif (empty($relationship->secondType)) { $relationship->secondType = $_class; $relationship->secondId = $_id; } if (!$relationship->save()) { // Validation errors $this->response['errors'] = $relationship->errors; $this->send(422); } else { $this->responseBody = $relationship; if ($method === 'POST') { // Set location header and respond with "201 Created" $this->response->httpHeader['Location'] = $this->createAbsoluteUrl('/api2/relationships', array('_class' => $_class, '_id' => $_id, '_relatedId' => $_relatedId)); $this->send(201, "Relationship created successfully"); } } break; case 'DELETE': if (!$relationship instanceof Relationships) { $this->send(400, "Cannot delete relationships without specifying which one to delete."); } if ($relationship->delete()) { $this->sendEmpty("Relationship {$_relatedId} deleted successfully."); } else { $this->send(500, "Failed to delete relationship #{$_relatedId}. It may have been deleted already."); } break; } }