Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ public function inventory(
}

// The first line of a CSV v3 file is our configuration
fgetcsv($handle);
fgetcsv($handle, escape: '\\');

while(($data = fgetcsv($handle)) !== false) {
while(($data = fgetcsv($handle, escape: '\\')) !== false) {
// The source key is always the first field in each line, make sure it is not empty

if(!empty($data[0]) && !ctype_space($data[0])) {
Expand Down Expand Up @@ -306,9 +306,9 @@ protected function processChangeList(
}

// Ignore the header line
fgetcsv($handle);
fgetcsv($handle, escape: '\\');

while(($data = fgetcsv($handle)) !== false) {
while(($data = fgetcsv($handle, escape: '\\')) !== false) {
// Implode the record back together for string comparison purposes.
// This may not be the same as the original line due to quotes, etc.
// $data[0] is the SORID
Expand All @@ -327,9 +327,9 @@ protected function processChangeList(
}

// Ignore the header line
fgetcsv($handle);
fgetcsv($handle, escape: '\\');

while(($data = fgetcsv($handle)) !== false) {
while(($data = fgetcsv($handle, escape: '\\')) !== false) {
// $data[0] is the SORID
if(array_key_exists($data[0], $knownRecords)) {
$newData = implode(',', $data);
Expand Down Expand Up @@ -445,7 +445,7 @@ protected function readFieldConfig(
}

// The first line is our configuration
$cfg = fgetcsv($handle);
$cfg = fgetcsv($handle, escape: '\\');

fclose($handle);

Expand Down Expand Up @@ -700,13 +700,13 @@ public function retrieve(
// If there is more than one record, we'll return the first one we find.

// The first line of a CSV v3 file is our configuration
fgetcsv($handle);
fgetcsv($handle, escape: '\\');

// Set null defaults in case we don't find a matching record
$ret['source_record'] = null;
$ret['entity_data'] = null;

while(($data = fgetcsv($handle)) !== false) {
while(($data = fgetcsv($handle, escape: '\\')) !== false) {
if($data[0] == $source_key) {
// This is our record

Expand Down Expand Up @@ -809,9 +809,9 @@ public function search(
}

// The first line of a CSV v3 file is our configuration
fgetcsv($handle);
fgetcsv($handle, escape: '\\');

while(($data = fgetcsv($handle)) !== false) {
while(($data = fgetcsv($handle, escape: '\\')) !== false) {
// strtolower, previous behavior was full string only so dupe that

$match = collection($data)
Expand Down
27 changes: 14 additions & 13 deletions app/plugins/CoreJob/src/Lib/Jobs/SyncJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,21 +238,22 @@ protected function fullSync() {

/**
* Cache the current run context.
*
*
* @param JobsTable $JobsTable $JobsTable JobsTable
* @param JobHistoryRecordsTable $JobHistoryRecordsTable $JobHistoryRecordsTable JobHistoryRecordsTable
* @param Job $job Current Job
* @param array $parameters Job Parameters (from the command line)
* @param int|null $eisId External Identity Source ID
* @return \StdClass
* @since COmanage Registry v5.0.0
* @param JobsTable $JobsTable JobsTable
* @param JobHistoryRecordsTable $JobHistoryRecordsTable JobHistoryRecordsTable
* @param Job $job Current Job
* @param array $parameters Job Parameters (from the command line)
* @param int $eisId External Identity Source ID
*/

protected function getRunContext(
\App\Model\Table\JobsTable $JobsTable,
\App\Model\Table\JobHistoryRecordsTable $JobHistoryRecordsTable,
\App\Model\Entity\Job $job,
array $parameters,
int $eisId=null
?int $eisId = null
): \StdClass {
// We use $runContext so we don't have to pass a complicated set of parameters around.

Expand Down Expand Up @@ -451,7 +452,7 @@ public function run(
);

if($this->runContext->eis->status == SyncModeEnum::Disabled) {
throw new \InvalidArgumentException('core_job', 'Sync.error.disabled');
throw new \InvalidArgumentException(__d('core_job', 'Sync.error.disabled'));
}

if(!empty($parameters['source_keys'])) {
Expand All @@ -465,7 +466,7 @@ public function run(
if(count($keys) == 1) {
$referenceId = $parameters['reference_id'];
} else {
throw new \InvalidArgumentException('core_job', 'Sync.error.reference_id');
throw new \InvalidArgumentException(__d('core_job', 'Sync.error.reference_id'));
}
}

Expand Down Expand Up @@ -516,11 +517,11 @@ public function run(
*
* @since COmanage Registry v5.0.0
* @param string $key Source Key to process
* @param string $referenceId Reference ID to link to record, if known
* @param string|null $referenceId Reference ID to link to record, if known
* @return bool True if processing should continue, false otherwise
*/

protected function syncRecord(string $key, string $referenceId=null): bool {
protected function syncRecord(string $key, ?string $referenceId=null): bool {
// comment and status for HistoryRecords
$c = "unknown";
$s = JobStatusEnum::Failed;
Expand Down Expand Up @@ -577,9 +578,9 @@ protected function syncRecord(string $key, string $referenceId=null): bool {
if($this->runContext->JobsTable->isCanceled($this->runContext->job->id)) {
// The Job was already marked Canceled, but we can optionally add a History Record
$this->runContext->JobHistoryRecordsTable->record(
jobId: $job->id,
jobId: $this->runContext->job->id,
recordKey: "",
comment: __d(
comment: __d(
'core_job',
'Sync.finish_summary.count',
[$this->runContext->created, $this->runContext->updated, $this->runContext->errors, $this->runContext->count]
Expand Down
19 changes: 12 additions & 7 deletions app/plugins/CoreServer/src/Model/Table/Oauth2ServersTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,23 @@ public function exchangeCode(int|string $id, string $code, string $redirectUri,
/**
* Obtain an OAuth token.
*
* @param Integer $id Oauth2Server ID
* @param String $grantType OAuth grant type
* @param String|null $code Access code returned by call to /oauth/authorize, for authorization_code grant
* @param String|null $redirectUri Callback URL used for initial request, for authorization_code grant
* @param Boolean $store If true, store the retrieved tokens in the Oauth2Server configuration
* @param int $id Oauth2Server ID
* @param string $grantType OAuth grant type
* @param string|null $code Access code returned by call to /oauth/authorize, for authorization_code grant
* @param string|null $redirectUri Callback URL used for initial request, for authorization_code grant
* @param bool $store If true, store the retrieved tokens in the Oauth2Server configuration
* @return mixed Object of data as returned by server, including access and refresh token
* @throws RuntimeException
*@since COmanage Registry v5.2.0
*/

public function obtainToken(int $id, string $grantType, string $code=null, string $redirectUri=null, bool $store=true): mixed
{
public function obtainToken(
int $id,
string $grantType,
?string $code=null,
?string $redirectUri=null,
bool $store=true)
: mixed {
// Pull our configuration
$srvr = $this->get($id);

Expand Down
5 changes: 4 additions & 1 deletion app/src/Command/SetupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ public function execute(Arguments $args, ConsoleIo $io)
)
];

$coTable->People->save($person);
// Setup should not trigger provisioning side effects. Save with a provisioning-off hint.
$coTable->People->save($person, [
'provision' => false,
]);

// Write the salt file if not set in environment and file does not exist.
if(!env('SECURITY_SALT', null)) {
Expand Down
4 changes: 2 additions & 2 deletions app/src/Controller/StandardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -721,10 +721,10 @@ public function index() {
* Populate any auto view variables, as requested via AutoViewVarsTrait.
*
* @since COmanage Registry v5.0.0
* @param object $obj Current object (eg: from edit), if set
* @param object|null $obj Current object (eg: from edit), if set
*/

protected function populateAutoViewVars(object $obj=null) {
protected function populateAutoViewVars(?object $obj=null) {
/** var Cake\ORM\Table $table */
$table = $this->getCurrentTable();

Expand Down
8 changes: 6 additions & 2 deletions app/src/Lib/Random/RandomString.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,19 @@ public static function generateCode(): string {
* a token is not expected to be directly visible or handled by a human, but
* will (eg) be injected into a URL or a message.
*
* @param int $length Length of token
* @param string|null $allowedCharset Allowed characters
* @param string|null $regex Regex to match characters
*
* @return string Token
* @throws RandomException
* @since COmanage Registry v5.0.0
*/

public static function generateToken(
int $length = 16,
string $allowedCharset = null,
string $regex = null, // Permitted
?string $allowedCharset = null,
?string $regex = null, // Permitted
): string {
// Unlike App Keys, tokens don't have restrictions on characters.

Expand Down
2 changes: 1 addition & 1 deletion app/src/Lib/Traits/IndexQueryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public function getIndexQuery(bool $pickerMode = false, array $requestParams = [
// Initialize the Query Object
$query = $table->find();
// Get a pointer to my expression list
$newexp = $query->newExpr();
$newexp = $query->expr();
// The searchable attributes can have an AND or an OR conjunction. The first one is used from the filtering block
// while the second one from the picker vue module.
$newexp = $newexp->setConjunction($pickerMode ? 'OR' : 'AND');
Expand Down
12 changes: 6 additions & 6 deletions app/src/Lib/Util/DeliveryUtilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ public static function sendEmailFromTemplate(
subject: $template->getMessagePart('subject'),
body_text: $template->getMessagePart('body_text'),
body_html: $template->getMessagePart('body_html'),
cc: $template->cc,
bcc: $template->bcc,
replyTo: $template->reply_to
cc: $template->cc ?? '',
bcc: $template->bcc ?? '',
replyTo: $template->reply_to ?? ''
);
} else {
self::sendEmailToAddress(
Expand All @@ -192,9 +192,9 @@ public static function sendEmailFromTemplate(
subject: $template->getMessagePart('subject'),
body_text: $template->getMessagePart('body_text'),
body_html: $template->getMessagePart('body_html'),
cc: $template->cc,
bcc: $template->bcc,
replyTo: $template->reply_to
cc: $template->cc ?? '',
bcc: $template->bcc ?? '',
replyTo: $template->reply_to ?? ''
);

return [
Expand Down
8 changes: 4 additions & 4 deletions app/src/Model/Table/JobsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public function assign(Job $job) {
__d('error',
'Jobs.status.invalid',
[
$jobs->id,
$job->id,
__d('enumeration', 'JobStatusEnum.Queued'),
__d('enumeration', 'JobStatusEnum.Assigned'),
__d('enumeration', 'JobStatusEnum.'.$job->status)
Expand Down Expand Up @@ -417,7 +417,7 @@ public function finish(Job $job, string $summary="", string $result=JobStatusEnu
// The new job will be substantially the same as the last one...

$this->register(
coId: job->co_id,
coId: $job->co_id,
plugin: $job->plugin,
parameters: json_decode($job->parameters, true),
registerSummary: $job->register_summary,
Expand Down Expand Up @@ -471,7 +471,7 @@ public function process(Job $job, string $dbcxn='default') {
__d('error',
'Jobs.status.invalid',
[
$jobs->id,
$job->id,
__d('enumeration', 'JobStatusEnum.Assigned'),
__d('enumeration', 'JobStatusEnum.InProgress'),
__d('enumeration', 'JobStatusEnum.'.$job->status)
Expand Down Expand Up @@ -687,7 +687,7 @@ public function start(Job $job, string $summary="") {
__d('error',
'Jobs.status.invalid',
[
$job->id,
$job->id,
__d('enumeration', 'JobStatusEnum.Assigned'),
__d('enumeration', 'JobStatusEnum.InProgress'),
__d('enumeration', 'JobStatusEnum.'.$job->status)
Expand Down
10 changes: 7 additions & 3 deletions app/src/Model/Table/PeopleTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,16 @@ public function implementedEvents(): array {
public function localAfterSave(\Cake\Event\EventInterface $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options): bool {
$this->recordHistory($entity);

// XXX implement this eventually?
//$provision = (isset($options['provision']) ? $options['provision'] : true);
// SetupCommand and other bootstrapping operations must be able to save People without
// triggering provisioning side effects
$provision = true;
if (isset($options['provision'])) {
$provision = (bool)$options['provision'];
}

if(!$entity->deleted) {
// If the entity was deleted we handled this in beforeDelete, above
$this->reconcileCoMembersGroupMemberships($entity);
$this->reconcileCoMembersGroupMemberships($entity, $provision);
}

return true;
Expand Down
6 changes: 6 additions & 0 deletions app/src/Model/Table/PluginsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ public function getPluginSchema(\App\Model\Entity\Plugin $plugin): ?object {
public function pluginPath(\App\Model\Entity\Plugin $plugin, string $file): string {
$fileName = $this->paths[$plugin->location]['path'] . DS . $plugin->plugin . DS . $file;

// "tests/" is optional in deployed environments. Return the computed path
// without treating absence as an error so callers can probe as needed.
if($file === 'tests' || str_starts_with($file, 'tests' . DS)) {
return $fileName;
}

if(is_readable($fileName)) {
// This is the plugin we're looking for
$this->llog('debug', "Found plugin $plugin->plugin in $plugin->location directory");
Expand Down
3 changes: 1 addition & 2 deletions app/src/Model/Table/VerificationsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,12 @@ public function requestCodeForPetition(
int $codeLength,
?string $codeCharset,
?string $codeRegex,
int $verificationId = null
?int $verificationId = null
): int {
// First generate a new code
$code = RandomString::generateToken($codeLength, $codeCharset, $codeRegex);
$expiry = date('Y-m-d H:i:s', time() + ($validity * 60));

$verification = null;

// If there's already a Verification, pull it, check it, and update it
if($verificationId) {
Expand Down
17 changes: 9 additions & 8 deletions app/src/View/Helper/FieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public function constructSPAField(string $element, string $vueElementName): stri

public function dateField(string $fieldName,
string $dateType = DateTypeEnum::Standard,
array $fieldArgs = null): string
?array $fieldArgs = null): string
{
// Initialize
$dateFormat = $dateType === DateTypeEnum::DateOnly ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss';
Expand Down Expand Up @@ -422,13 +422,13 @@ public function dateField(string $fieldName,
* @since COmanage Registry v5.0.0
*/
public function formField(string $fieldName,
array $fieldOptions = null,
string $fieldLabel = null,
?array $fieldOptions = null,
?string $fieldLabel = null,
string $fieldPrefix = '',
string $fieldType = null,
array $fieldSelectOptions = null,
string $fieldNameAlias = null,
bool $labelIsTextOnly = null): string
?string $fieldType = null,
?array $fieldSelectOptions = null,
?string $fieldNameAlias = null,
?bool $labelIsTextOnly = null): string
{
$fieldArgs = $fieldOptions ?? [];
$fieldArgs['label'] = $fieldOptions['label'] ?? false;
Expand Down Expand Up @@ -766,7 +766,8 @@ public function restructureFieldArguments(array $fieldArgs) {
'id',
'style',
'checked',
'label'
'label',
'name'
];

// Remove the top-level field options that are intended for Cake, and
Expand Down
2 changes: 1 addition & 1 deletion app/src/View/Helper/TabHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public function tabBelongsToModelPath(string $tab, string $modelFullName, int &$
* @return int
* @since COmanage Registry v5.0.0
*/
public function getCurrentId(string $tabName = null, bool $isNested = false): int
public function getCurrentId(?string $tabName = null, bool $isNested = false): int
{
$vv_obj = $this->getView()->get('vv_obj');
$vv_primary_link = $this->getView()->get('vv_primary_link');
Expand Down