Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace SqlConnector\Model\Table;

use App\Model\Entity\ProvisioningTarget;
use Cake\Datasource\ConnectionManager;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
Expand Down Expand Up @@ -230,8 +231,7 @@ class SqlProvisionersTable extends Table {
'source' => 'TermsAndConditions',
'source_table' => 'terms_and_conditions',
'related' => [],
'archives' => true,
'callback' => 'processTAndC'
'archives' => true
],
'Types' => [
'table' => 'types',
Expand Down Expand Up @@ -372,39 +372,16 @@ public function localAfterSave(\Cake\Event\EventInterface $event, \Cake\Datasour
return true;
}

/**
* Process T&C for export, by converting Mostly Static Pages to their URLs.
*
* @since COmanage Registry v5.3.0
* @param array $row Result row from query
*/

protected function processTAndC(array $row) {
if(!empty($row['mostly_static_page_id'])
// If both a URL and MSP are specified, the URL takes precedence
&& empty($row['url'])) {
// Map the MSP to its URL and include that instead
$MSPTable = TableRegistry::getTableLocator()->get("MostlyStaticPages");

$msp = $MSPTable->get($row['mostly_static_page_id']);

$row['url'] = $msp->url;
}

return $row;
}

/**
* Provision object data to the provisioning target.
*
* @since COmanage Registry v5.0.0
* @param ProvisioningTarget $provisioningTarget SqlProvisioner configuration
* @param string $className Class name of primary object being provisioned
* @param object $data Provisioning data in Entity format (eg: \App\Model\Entity\Person)
* @param ProvisioningEligibilityEnum $eligibility Provisioning Eligibility Enum
*
* @param ProvisioningTarget $provisioningTarget SqlProvisioner configuration
* @param string $className Class name of primary object being provisioned
* @param object $data Provisioning data in Entity format (eg: \App\Model\Entity\Person)
* @param string $eligibility Provisioning Eligibility Enum
* @return array Array of status, comment, and optional identifier
* @since COmanage Registry v5.0.0
*/

public function provision(
\App\Model\Entity\ProvisioningTarget $provisioningTarget,
string $className,
Expand Down Expand Up @@ -494,12 +471,12 @@ public function status(
* Sync an entity to the target database schema.
*
* @since COmanage Registry v5.0.0
* @param SqlProvisioner $SqlProvisioner SqlProvisioner configuration
* @param string $entityName Entity name of primary object being provisioned
* @param object $data Provisioning data in Entity format (eg: \App\Model\Entity\Person)
* @param ProvisioningEligibilityEnum $eligibility Provisioning Eligibility Enum
* @param string $dataSource Datasource to provision to
* @return array Array of status, comment, and optional identifier
* @param \SqlConnector\Model\Entity\SqlProvisioner $SqlProvisioner SqlProvisioner configuration
* @param string $entityName Entity name of primary object being provisioned
* @param object $data Provisioning data in Entity format (eg: \App\Model\Entity\Person)
* @param string $eligibility Provisioning Eligibility Enum
* @param string $dataSource Datasource to provision to
* @return array Array of status, comment, and optional identifier
*/

protected function syncEntity(
Expand Down Expand Up @@ -759,12 +736,12 @@ public function syncReferenceData(int $id, string $dataSource='targetdb') {
* Sync related entities to the target database schema.
*
* @since COmanage Registry v5.0.0
* @param SqlProvisioner $SqlProvisioner SqlProvisioner configuration
* @param string $parentEntityName Entity name of primary object being provisioned
* @param string $relatedEntityName Entity name of related object being provisioned
* @param object $parentData Provisioning data in Entity format (eg: \App\Model\Entity\Person) for parent
* @param ProvisioningEligibilityEnum $eligibility Provisioning Eligibility Enum
* @param string $dataSource Datasource to provision to
* @param \SqlConnector\Model\Entity\SqlProvisioner $SqlProvisioner SqlProvisioner configuration
* @param string $parentEntityName Entity name of primary object being provisioned
* @param string $relatedEntityName Entity name of related object being provisioned
* @param object $parentData Provisioning data in Entity format (eg: \App\Model\Entity\Person) for parent
* @param string $eligibility Provisioning Eligibility Enum
* @param string $dataSource Datasource to provision to
*/

protected function syncRelatedEntities(
Expand Down
2 changes: 1 addition & 1 deletion app/config/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@
\Cake\Utility\Inflector::rules('uninflected', ['cous' => 'cous']);
\Cake\Utility\Inflector::rules('irregular', ['meta' => 'meta']);
// \Cake\Utility\Inflector::rules('irregular', ['terms_and_condition' => 'terms_and_conditions']);
\Cake\Utility\Inflector::rules('uninflected', ['terms_and_conditions' => 'terms_and_conditions']);
\Cake\Utility\Inflector::rules('uninflected', ['TermsAndConditions', 'terms_and_conditions']);

/*
* Define some constants
Expand Down
16 changes: 0 additions & 16 deletions app/src/Controller/TermsAndConditionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,6 @@ public function agree(string $id) {
return $this->redirect(['action' => 'review', '?' => ['co_id' => $this->getCOID()]]);
}

/**
* Callback run prior to the request render.
*
* @since COmanage Registry v5.1.0
* @param EventInterface $event Cake Event
* @return \Cake\Http\Response HTTP Response
*/

public function beforeRender(\Cake\Event\EventInterface $event) {
$this->set('vv_base_url', \Cake\Routing\Router::url(
url: "/" . $this->getCOID(),
full: true
));

return parent::beforeRender($event);
}

/**
* Proxy an Agreement on behalf of a Person.
Expand Down
38 changes: 37 additions & 1 deletion app/src/Model/Entity/TAndCAgreement.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,50 @@

namespace App\Model\Entity;

use Cake\Core\Configure;
use Cake\ORM\Entity;
use Cake\ORM\TableRegistry;

class TAndCAgreement extends Entity {
use \App\Lib\Traits\EntityMetaTrait;

use \App\Lib\Traits\LabeledLogTrait;

protected array $_accessible = [
'*' => true,
'id' => false,
'slug' => false,
];

/**
* Get the URL for this Terms and Conditions Agreement.
*
* @since COmanage Registry v5.3.0
* @return string|null URL
*/

protected function _getUrl(): ?string {
// If the associated TermsAndConditions is already loaded, check it first
if(!empty($this->terms_and_conditions)) {
return $this->terms_and_conditions->url;
}

// Otherwise look up the Terms and Conditions if terms_and_conditions_id is present
if(!empty($this->terms_and_conditions_id)) {
try {
$TermsAndConditions = TableRegistry::getTableLocator()->get('TermsAndConditions');

return $TermsAndConditions->get($this->terms_and_conditions_id)->url;
} catch(\Exception $e) {
// We will rethrow here to facilitate debugging
if (Configure::read('debug')) {
throw $e;
}

$this->llog('error', $e->getMessage());
return null;
}
}

return null;
}
}
41 changes: 40 additions & 1 deletion app/src/Model/Entity/TermsAndConditions.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,53 @@

namespace App\Model\Entity;

use Cake\Core\Configure;
use Cake\ORM\Entity;
use Cake\ORM\TableRegistry;

class TermsAndConditions extends Entity {
use \App\Lib\Traits\EntityMetaTrait;

use \App\Lib\Traits\LabeledLogTrait;

protected array $_accessible = [
'*' => true,
'id' => false,
'slug' => false,
];

/**
* Get the URL for this Terms and Conditions as a virtual field.
*
* @param string|null $url Existing URL field value
* @return string|null URL
* @throws \Exception
* @since COmanage Registry v5.3.0
*/
protected function _getUrl(?string $url = null): ?string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this call is on the entity rather than the table to facilitate the lookup in SqlProvisioner? Does the find() on $SrcTable in syncReferenceData() correctly populate url even though it's a virtual field? (If not, we'll need to add the callback back in, and then this call could move to the Table to simplify the lookup in TAndCAgreement.php.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this call is on the entity rather than the table to facilitate the lookup in SqlProvisioner?

Yes, placing _getUrl() on the TermsAndConditions entity encapsulates the fallback logic directly on the data object, allowing $tc->url to resolve automatically across the entire codebase, including SqlProvisioner, TAndCAgreement, REST APIs, and templates, without requiring callers to instantiate or query a table helper.

Does the find() on $SrcTable in syncReferenceData() correctly populate url even though it's a virtual field? (If not, we'll need to add the callback back in, and then this call could move to the Table to simplify the lookup in TAndCAgreement.php.)

Yes, because url is a physical database column, CakePHP tracks it in the entity's visible fields upon hydration from $SrcTable->find(), and $r->toArray() automatically invokes _getUrl(?string $url) during serialization to populate the resolved Mostly Static Page URL into the target record without needing the processTAndC callback.

if(!empty($url)) {
return $url;
}

if(!empty($this->mostly_static_page?->url)) {
return $this->mostly_static_page->url;
}

if(!empty($this->mostly_static_page_id)) {
try {
$MSPTable = TableRegistry::getTableLocator()->get('MostlyStaticPages');
$msp = $MSPTable->get($this->mostly_static_page_id);
return $msp->url;
} catch(\Exception $e) {
// We will rethrow here to facilitate debugging
if (Configure::read('debug')) {
throw $e;
}

$this->llog('error', $e->getMessage());
return null;
}
}

return null;
}
}
5 changes: 5 additions & 0 deletions app/src/Model/Table/PeopleTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ public function marshalProvisioningData(int $id): array {
'Types'
],
'Pronouns',
// TAndCAgreements are provisionable sub-objects, but TermsAndConditions
// and MostlyStaticPages are configuration and are not provisionable.
// We do not contain TermsAndConditions => MostlyStaticPages here to maintain
// loose coupling and avoid synchronization/ownership issues; provisioners
// can resolve the T&C URL via the TAndCAgreement virtual field or reference data.
'TAndCAgreements',
'TelephoneNumbers' => [ 'Types' ],
'Urls' => [ 'Types' ]
Expand Down
9 changes: 1 addition & 8 deletions app/templates/TermsAndConditions/columns.inc
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@ $rowActions = [
[
'icon' => 'arrow_outward',
'label' => __d('operation', 'visit.tandc'),
'callbackUrl' => function($entity) use ($vv_base_url) {
// There should always be either a Mostly Static Page or a URL to reference.
if(!empty($entity->mostly_static_page->name)) {
// The T&C is a mostly static page. Provide a link to it.
return $vv_base_url . '/' . $entity->mostly_static_page->name;
}
return $entity->url;
}
'callbackUrl' => static fn($entity) => $entity->url
]
];