From 80142510a54c4673da1bb293dc280472c0a462fb Mon Sep 17 00:00:00 2001 From: Kaitlin Newson Date: Fri, 25 Jul 2025 11:00:06 -0300 Subject: [PATCH 1/5] pkp/pkp-lib#10671 update plugin to follow code formatting standards --- CustomHeaderPlugin.php | 279 ++++++++++++++++++----------------- CustomHeaderSettingsForm.php | 159 ++++++++++---------- README.md | 6 +- 3 files changed, 225 insertions(+), 219 deletions(-) diff --git a/CustomHeaderPlugin.php b/CustomHeaderPlugin.php index 91a859c..534e906 100644 --- a/CustomHeaderPlugin.php +++ b/CustomHeaderPlugin.php @@ -3,8 +3,8 @@ /** * @file CustomHeaderPlugin.php * - * Copyright (c) 2013-2023 Simon Fraser University - * Copyright (c) 2003-2023 John Willinsky + * Copyright (c) 2013-2025 Simon Fraser University + * Copyright (c) 2003-2025 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file LICENSE. * * @brief CustomHeader plugin class @@ -12,145 +12,146 @@ namespace APP\plugins\generic\customHeader; -use PKP\plugins\GenericPlugin; +use APP\template\TemplateManager; +use APP\core\Application; +use Exception; use PKP\config\Config; -use PKP\plugins\Hook; +use PKP\core\JSONMessage; use PKP\linkAction\LinkAction; use PKP\linkAction\request\AjaxModal; -use PKP\core\JSONMessage; -use APP\i18n\AppLocale; -use APP\template\TemplateManager; -use APP\core\Application; - -class CustomHeaderPlugin extends GenericPlugin { - /** @var bool Whether or not the header has been injected */ - var $injected = false; - - /** - * @copydoc Plugin::register() - */ - function register($category, $path, $mainContextId = null) { - $success = parent::register($category, $path, $mainContextId); - if (!Config::getVar('general', 'installed') || defined('RUNNING_UPGRADE')) return true; - if ($success && $this->getEnabled()) { - // Insert CustomHeader page tag to page header - Hook::add('TemplateManager::display', array($this, 'displayTemplateHook')); - // Insert custom script to the page footer - Hook::add('Templates::Common::Footer::PageFooter', array($this, 'insertFooter')); - } - return $success; - } - - /** - * Get the plugin display name. - * @return string - */ - function getDisplayName() { - return __('plugins.generic.customHeader.displayName'); - } - - /** - * Get the plugin description. - * @return string - */ - function getDescription() { - return __('plugins.generic.customHeader.description'); - } - - /** - * @copydoc Plugin::getActions() - */ - function getActions($request, $verb) { - $router = $request->getRouter(); - return array_merge( - $this->getEnabled()?array( - new LinkAction( - 'settings', - new AjaxModal( - $router->url($request, null, null, 'manage', null, array('verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic')), - $this->getDisplayName() - ), - __('manager.plugins.settings'), - null - ), - ):array(), - parent::getActions($request, $verb) - ); - } - - /** - * @copydoc Plugin::manage() - */ - function manage($args, $request) { - switch ($request->getUserVar('verb')) { - case 'settings': - $context = $request->getContext(); - - $templateMgr = TemplateManager::getManager($request); - $form = new CustomHeaderSettingsForm($this, $context?$context->getId():CONTEXT_ID_NONE); - - if ($request->getUserVar('save')) { - $form->readInputData(); - if ($form->validate()) { - $form->execute(); - return new JSONMessage(true); - } - } else { - $form->initData(); - } - return new JSONMessage(true, $form->fetch($request)); - } - return parent::manage($args, $request); - } - - /** - * Register the CustomHeader script tag - * @param $hookName string - * @param $params array - */ - function displayTemplateHook($hookName, $params) { - if (!$this->injected) { - $this->injected = true; - $templateMgr =& $params[0]; - $request = Application::get()->getRequest(); - $context = $request->getContext(); - $templateMgr->addHeader('custom', $this->getSetting($context?$context->getId():CONTEXT_ID_NONE, 'content')); - $templateMgr->addHeader('custombackend', $this->getSetting($context?$context->getId():CONTEXT_ID_NONE, 'backendContent'), ['contexts' => ['backend']]); - } - return false; - } - - /** - * Add custom footer to the page - * - * @param $hookName string - * @param $params array - */ - function insertFooter($hookName, $params) { - $templateMgr =& $params[0]; - $output =& $params[2]; - $request = Application::get()->getRequest(); - $context = $request->getContext(); - - $output .= $this->getSetting($context?$context->getId():CONTEXT_ID_NONE, 'footerContent'); - - return false; - } - - /** - * This plugin can be used site-wide or in a specific context. The - * isSitePlugin check is used to grant access to different users, so this - * plugin must return true only if the user is currently in the site-wide - * context. - * - * @see PluginGridRow::_canEdit() - * @return boolean - */ - function isSitePlugin() { - return !(Application::get()->getRequest()->getContext()); - } -} +use PKP\plugins\GenericPlugin; +use PKP\plugins\Hook; -if (!PKP_STRICT_MODE) { - class_alias('\APP\plugins\generic\customHeader\CustomHeaderPlugin', '\CustomHeaderPlugin'); +class CustomHeaderPlugin extends GenericPlugin +{ + /** Whether the header has been injected */ + public bool $injected = false; + + /** + * @copydoc Plugin::register() + * @throws Exception + */ + public function register($category, $path, $mainContextId = null): bool + { + $success = parent::register($category, $path, $mainContextId); + if (!Config::getVar('general', 'installed') || defined('RUNNING_UPGRADE')) { + return true; + } + if ($success && $this->getEnabled()) { + // Insert CustomHeader page tag to page header + Hook::add('TemplateManager::display', array($this, 'displayTemplateHook')); + // Insert custom script to the page footer + Hook::add('Templates::Common::Footer::PageFooter', array($this, 'insertFooter')); + } + return $success; + } + + /** + * Get the plugin display name. + */ + public function getDisplayName(): string + { + return __('plugins.generic.customHeader.displayName'); + } + + /** + * Get the plugin description. + */ + public function getDescription(): string + { + return __('plugins.generic.customHeader.description'); + } + + /** + * @copydoc Plugin::getActions() + */ + public function getActions($request, $verb): array + { + $router = $request->getRouter(); + return array_merge( + $this->getEnabled() ? array( + new LinkAction( + 'settings', + new AjaxModal( + $router->url($request, null, null, 'manage', null, array('verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic')), + $this->getDisplayName() + ), + __('manager.plugins.settings'), + null + ), + ) : array(), + parent::getActions($request, $verb) + ); + } + + /** + * @copydoc Plugin::manage() + * @throws Exception + */ + public function manage($args, $request) + { + switch ($request->getUserVar('verb')) { + case 'settings': + $context = $request->getContext(); + + $templateMgr = TemplateManager::getManager($request); + $form = new CustomHeaderSettingsForm($this, $context ? $context->getId() : CONTEXT_ID_NONE); + + if ($request->getUserVar('save')) { + $form->readInputData(); + if ($form->validate()) { + $form->execute(); + return new JSONMessage(true); + } + } else { + $form->initData(); + } + return new JSONMessage(true, $form->fetch($request)); + } + return parent::manage($args, $request); + } + + /** + * Register the CustomHeader script tag + */ + public function displayTemplateHook(string $hookName, array $params) + { + if (!$this->injected) { + $this->injected = true; + $templateMgr =& $params[0]; + $request = Application::get()->getRequest(); + $context = $request->getContext(); + $templateMgr->addHeader('custom', $this->getSetting($context ? $context->getId() : CONTEXT_ID_NONE, 'content')); + $templateMgr->addHeader('custombackend', $this->getSetting($context ? $context->getId() : CONTEXT_ID_NONE, 'backendContent'), ['contexts' => ['backend']]); + } + return false; + } + + /** + * Add custom footer to the page + */ + public function insertFooter(string $hookName, array $params) + { + $templateMgr =& $params[0]; + $output =& $params[2]; + $request = Application::get()->getRequest(); + $context = $request->getContext(); + + $output .= $this->getSetting($context ? $context->getId() : CONTEXT_ID_NONE, 'footerContent'); + + return false; + } + + /** + * This plugin can be used site-wide or in a specific context. The + * isSitePlugin check is used to grant access to different users, so this + * plugin must return true only if the user is currently in the site-wide + * context. + * + * @see PluginGridRow::_canEdit() + */ + public function isSitePlugin(): bool + { + return !(Application::get()->getRequest()->getContext()); + } } diff --git a/CustomHeaderSettingsForm.php b/CustomHeaderSettingsForm.php index 1a0bba1..afb2a18 100644 --- a/CustomHeaderSettingsForm.php +++ b/CustomHeaderSettingsForm.php @@ -3,8 +3,8 @@ /** * @file CustomHeaderSettingsForm.php * - * Copyright (c) 2013-2023 Simon Fraser University - * Copyright (c) 2003-2023 John Willinsky + * Copyright (c) 2013-2025 Simon Fraser University + * Copyright (c) 2003-2025 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file LICENSE. * * @brief Form for managers to modify custom header plugin settings @@ -12,91 +12,96 @@ namespace APP\plugins\generic\customHeader; -use PKP\form\Form; +use DOMDocument; use APP\core\Application; -use APP\template\TemplateManager; use APP\notification\NotificationManager; +use APP\template\TemplateManager; +use PKP\form\Form; +use PKP\form\validation\FormValidatorCSRF; +use PKP\form\validation\FormValidatorCustom; +use PKP\form\validation\FormValidatorPost; -class CustomHeaderSettingsForm extends Form { - - /** @var int */ - var $_contextId; - - /** @var object */ - var $_plugin; +class CustomHeaderSettingsForm extends Form +{ + public int $contextId; + public CustomHeaderPlugin $plugin; - /** - * Constructor - * @param $plugin CustomHeaderPlugin - * @param $contextId int - */ - function __construct($plugin, $contextId) { - $this->_contextId = $contextId; - $this->_plugin = $plugin; + /** + * Constructor + */ + public function __construct(CustomHeaderPlugin $plugin, int $contextId) + { + $this->contextId = $contextId; + $this->plugin = $plugin; - parent::__construct($plugin->getTemplateResource('settingsForm.tpl')); + parent::__construct($plugin->getTemplateResource('settingsForm.tpl')); - $this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'backendContent', FORM_VALIDATOR_OPTIONAL_VALUE, 'plugins.generic.customHeader.backendContent.error', function ($backendContent) { return $this->validateWellFormed($backendContent); })); - $this->addCheck(new \PKP\form\validation\FormValidatorPost($this)); - $this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this)); - } + $this->addCheck(new FormValidatorCustom($this, 'backendContent', FORM_VALIDATOR_OPTIONAL_VALUE, 'plugins.generic.customHeader.backendContent.error', function ($backendContent) { + return $this->validateWellFormed($backendContent); + })); + $this->addCheck(new FormValidatorPost($this)); + $this->addCheck(new FormValidatorCSRF($this)); + } - /** - * Initialize form data. - */ - function initData() { - $this->_data = array( - 'content' => $this->_plugin->getSetting($this->_contextId, 'content'), - 'backendContent' => $this->_plugin->getSetting($this->_contextId, 'backendContent'), - 'footerContent' => $this->_plugin->getSetting($this->_contextId, 'footerContent') - ); - } + /** + * Initialize form data. + */ + public function initData(): void + { + $this->_data = array( + 'content' => $this->plugin->getSetting($this->contextId, 'content'), + 'backendContent' => $this->plugin->getSetting($this->contextId, 'backendContent'), + 'footerContent' => $this->plugin->getSetting($this->contextId, 'footerContent') + ); + } - /** - * Assign form data to user-submitted data. - */ - function readInputData() { - $this->readUserVars(array('content', 'backendContent', 'footerContent')); - } + /** + * Assign form data to user-submitted data. + */ + public function readInputData(): void + { + $this->readUserVars(array('content', 'backendContent', 'footerContent')); + } - /** - * Fetch the form. - * @copydoc Form::fetch() - */ - function fetch($request, $template = null, $display = false) { - $templateMgr = TemplateManager::getManager($request); - $templateMgr->assign('pluginName', $this->_plugin->getName()); - return parent::fetch($request, $template, $display); - } + /** + * Fetch the form. + * @copydoc Form::fetch() + */ + public function fetch($request, $template = null, $display = false): null|string + { + $templateMgr = TemplateManager::getManager($request); + $templateMgr->assign('pluginName', $this->plugin->getName()); + return parent::fetch($request, $template, $display); + } - /** - * Save settings. - */ - function execute(...$functionArgs) { - parent::execute(...$functionArgs); + /** + * Save settings. + */ + public function execute(...$functionArgs): mixed + { + parent::execute(...$functionArgs); - $request = Application::get()->getRequest(); - $this->_plugin->updateSetting($this->_contextId, 'content', $this->getData('content'), 'string'); - $this->_plugin->updateSetting($this->_contextId, 'backendContent', $this->getData('backendContent'), 'string'); - $this->_plugin->updateSetting($this->_contextId, 'footerContent', $this->getData('footerContent'), 'string'); - $notificationManager = new NotificationManager(); - $notificationManager->createTrivialNotification($request->getUser()->getId(), NOTIFICATION_TYPE_SUCCESS); - } + $request = Application::get()->getRequest(); + $this->plugin->updateSetting($this->contextId, 'content', $this->getData('content'), 'string'); + $this->plugin->updateSetting($this->contextId, 'backendContent', $this->getData('backendContent'), 'string'); + $this->plugin->updateSetting($this->contextId, 'footerContent', $this->getData('footerContent'), 'string'); + $notificationManager = new NotificationManager(); + $notificationManager->createTrivialNotification($request->getUser()->getId(), NOTIFICATION_TYPE_SUCCESS); + } - /** - * Validate that the input is well-formed XML - * We want to avoid breaking the whole HTML page with an unclosed HTML attribute quote or tag - * @param $input string - * @return boolean - */ - function validateWellFormed($input) { - $libxml_errors_setting = libxml_use_internal_errors(); - libxml_use_internal_errors(true); - libxml_clear_errors(); - $dom = new DOMDocument(); - $dom->loadHTML($input); - $isWellFormed = count(libxml_get_errors())==0; - libxml_use_internal_errors($libxml_errors_setting); - return $isWellFormed; - } + /** + * Validate that the input is well-formed XML + * We want to avoid breaking the whole HTML page with an unclosed HTML attribute quote or tag + */ + public function validateWellFormed(string $input): bool + { + $libxml_errors_setting = libxml_use_internal_errors(); + libxml_use_internal_errors(true); + libxml_clear_errors(); + $dom = new DOMDocument(); + $dom->loadHTML($input); + $isWellFormed = count(libxml_get_errors()) == 0; + libxml_use_internal_errors($libxml_errors_setting); + return $isWellFormed; + } } diff --git a/README.md b/README.md index 9157d18..4c6c1ec 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ Custom Header Plugin ==================== -| main |3.4.0 | 3.3.0 | -|--------- | --- | ---- | -| [![customHeader](https://github.com/pkp/customHeader/actions/workflows/main.yml/badge.svg)](https://github.com/pkp/customHeader/actions/workflows/main.yml) | | [![customHeader](https://github.com/pkp/customHeader/actions/workflows/stable-3_3_0.yml/badge.svg)](https://github.com/pkp/customHeader/actions/workflows/stable-3_3_0.yml) | +| main | 3.4.0 | 3.3.0 | +|-------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [![customHeader](https://github.com/pkp/customHeader/actions/workflows/main.yml/badge.svg)](https://github.com/pkp/customHeader/actions/workflows/main.yml) | | [![customHeader](https://github.com/pkp/customHeader/actions/workflows/stable-3_3_0.yml/badge.svg)](https://github.com/pkp/customHeader/actions/workflows/stable-3_3_0.yml) | This is a plugin adding custom headers content to the webpage. From ff2197c95889b2fe599ad9b9cdb4230661a205f1 Mon Sep 17 00:00:00 2001 From: Kaitlin Newson Date: Fri, 25 Jul 2025 11:23:07 -0300 Subject: [PATCH 2/5] pkp/pkp-lib#10671 3.5 compatibility updates --- CustomHeaderPlugin.php | 27 +++++++++++++++++++-------- CustomHeaderSettingsForm.php | 4 ++-- templates/settingsForm.tpl | 7 +++---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/CustomHeaderPlugin.php b/CustomHeaderPlugin.php index 534e906..bf27628 100644 --- a/CustomHeaderPlugin.php +++ b/CustomHeaderPlugin.php @@ -12,11 +12,11 @@ namespace APP\plugins\generic\customHeader; -use APP\template\TemplateManager; use APP\core\Application; use Exception; use PKP\config\Config; use PKP\core\JSONMessage; +use PKP\core\PKPApplication; use PKP\linkAction\LinkAction; use PKP\linkAction\request\AjaxModal; use PKP\plugins\GenericPlugin; @@ -73,7 +73,7 @@ public function getActions($request, $verb): array new LinkAction( 'settings', new AjaxModal( - $router->url($request, null, null, 'manage', null, array('verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic')), + $router->url($request, null, null, 'manage', null, ['verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic']), $this->getDisplayName() ), __('manager.plugins.settings'), @@ -93,9 +93,10 @@ public function manage($args, $request) switch ($request->getUserVar('verb')) { case 'settings': $context = $request->getContext(); - - $templateMgr = TemplateManager::getManager($request); - $form = new CustomHeaderSettingsForm($this, $context ? $context->getId() : CONTEXT_ID_NONE); + $form = new CustomHeaderSettingsForm( + $this, + $context ? $context->getId() : PKPApplication::SITE_CONTEXT_ID + ); if ($request->getUserVar('save')) { $form->readInputData(); @@ -121,8 +122,18 @@ public function displayTemplateHook(string $hookName, array $params) $templateMgr =& $params[0]; $request = Application::get()->getRequest(); $context = $request->getContext(); - $templateMgr->addHeader('custom', $this->getSetting($context ? $context->getId() : CONTEXT_ID_NONE, 'content')); - $templateMgr->addHeader('custombackend', $this->getSetting($context ? $context->getId() : CONTEXT_ID_NONE, 'backendContent'), ['contexts' => ['backend']]); + $templateMgr->addHeader( + 'custom', + $this->getSetting($context ? $context->getId() : PKPApplication::SITE_CONTEXT_ID, 'content') + ); + $templateMgr->addHeader( + 'custombackend', + $this->getSetting( + $context ? $context->getId() : PKPApplication::SITE_CONTEXT_ID, + 'backendContent' + ), + ['contexts' => ['backend']] + ); } return false; } @@ -137,7 +148,7 @@ public function insertFooter(string $hookName, array $params) $request = Application::get()->getRequest(); $context = $request->getContext(); - $output .= $this->getSetting($context ? $context->getId() : CONTEXT_ID_NONE, 'footerContent'); + $output .= $this->getSetting($context ? $context->getId() : PKPApplication::SITE_CONTEXT_ID, 'footerContent'); return false; } diff --git a/CustomHeaderSettingsForm.php b/CustomHeaderSettingsForm.php index afb2a18..22229b8 100644 --- a/CustomHeaderSettingsForm.php +++ b/CustomHeaderSettingsForm.php @@ -77,7 +77,7 @@ public function fetch($request, $template = null, $display = false): null|string /** * Save settings. */ - public function execute(...$functionArgs): mixed + public function execute(...$functionArgs) { parent::execute(...$functionArgs); @@ -86,7 +86,7 @@ public function execute(...$functionArgs): mixed $this->plugin->updateSetting($this->contextId, 'backendContent', $this->getData('backendContent'), 'string'); $this->plugin->updateSetting($this->contextId, 'footerContent', $this->getData('footerContent'), 'string'); $notificationManager = new NotificationManager(); - $notificationManager->createTrivialNotification($request->getUser()->getId(), NOTIFICATION_TYPE_SUCCESS); + $notificationManager->createTrivialNotification($request->getUser()->getId()); } /** diff --git a/templates/settingsForm.tpl b/templates/settingsForm.tpl index 572bb62..49c26e9 100644 --- a/templates/settingsForm.tpl +++ b/templates/settingsForm.tpl @@ -1,8 +1,8 @@ {** * templates/settingsForm.tpl * - * Copyright (c) 2013-2023 Simon Fraser University - * Copyright (c) 2003-2023 John Willinsky + * Copyright (c) 2013-2025 Simon Fraser University + * Copyright (c) 2003-2025 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file LICENSE. * * Plugin settings @@ -15,7 +15,7 @@ $('#customHeaderSettingsForm').pkpHandler('$.pkp.controllers.form.AjaxFormHandler'); {rdelim}); -
+ {csrf}

{translate key="plugins.generic.customHeader.manager.settings.description"}

{include file="controllers/notification/inPlaceNotification.tpl" notificationId="customHeaderFormNotification"} @@ -37,4 +37,3 @@ {fbvFormButtons}
- From 0f6dcd8b2c984e9c76c08d6e18ae84c87005abd1 Mon Sep 17 00:00:00 2001 From: Kaitlin Newson Date: Fri, 25 Jul 2025 11:23:29 -0300 Subject: [PATCH 3/5] update tests --- .github/actions/tests.sh | 6 +-- .github/workflows/main.yml | 12 +++--- cypress/tests/functional/CustomHeader.cy.js | 44 +++++++++++---------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/.github/actions/tests.sh b/.github/actions/tests.sh index 2482793..1dd05e7 100755 --- a/.github/actions/tests.sh +++ b/.github/actions/tests.sh @@ -2,8 +2,4 @@ set -e -npx cypress run --spec "cypress/tests/data/10-Installation.spec.js,cypress/tests/data/20-CreateContext.spec.js" - -npx cypress run --headless --browser chrome --config '{"specPattern":["plugins/generic/customHeader/cypress/tests/functional/*.cy.js"]}' - - +npx cypress run --config specPattern=plugins/generic/customHeader/cypress/tests/functional diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b7589e8..71aca35 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -on: [push] +on: [push, pull_request] name: customHeader jobs: customHeader: @@ -43,12 +43,12 @@ jobs: - application: ops php-version: 8.2 database: pgsql - name: customHeader steps: - uses: pkp/pkp-github-actions@v1 with: - node_version: 20 - branch: main - repository: pkp - plugin: true + node_version: 20 + branch: main + repository: pkp + plugin: true + dataset_inject: true diff --git a/cypress/tests/functional/CustomHeader.cy.js b/cypress/tests/functional/CustomHeader.cy.js index 1538dd4..7fb53c3 100644 --- a/cypress/tests/functional/CustomHeader.cy.js +++ b/cypress/tests/functional/CustomHeader.cy.js @@ -1,33 +1,35 @@ /** * @file cypress/tests/functional/CustomHeader.cy.js * - * Copyright (c) 2014-2023 Simon Fraser University - * Copyright (c) 2000-2023 John Willinsky + * Copyright (c) 2014-2025 Simon Fraser University + * Copyright (c) 2000-2025 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file LICENSE. * */ -describe('Custom Header plugin tests', function() { - it('Creates and exercises a custom header', function() { - cy.login('admin', 'admin', 'publicknowledge'); +describe('Custom Header plugin tests', function () { + it('Creates and exercises a custom header', function () { + cy.login('admin', 'admin', 'publicknowledge'); - cy.get('.app__nav a').contains('Website').click(); - cy.get('button[id="plugins-button"]').click(); + cy.get('nav').contains('Settings').click(); + // Ensure submenu item click despite animation + cy.get('nav').contains('Website').click({ force: true }); + cy.get('button[id="plugins-button"]').click(); - // Find and enable the plugin - cy.get('input[id^="select-cell-customheaderplugin-enabled"]').click(); - cy.get('div:contains(\'The plugin "Custom Header Plugin" has been enabled.\')'); - cy.waitJQuery(); + // Find and enable the plugin + cy.get('input[id^="select-cell-customheaderplugin-enabled"]').click(); + cy.get('div:contains(\'The plugin "Custom Header Plugin" has been enabled.\')'); + cy.reload(); - cy.get('tr[id*="customheaderplugin"] a.show_extras').click(); - cy.get('a[id*="customheaderplugin-settings"]').click(); - cy.waitJQuery(2000); // Wait for form to settle - cy.get('textarea[id^="headerContent-"]').type('', {delay: 0}); - cy.get('textarea[id^="footerContent-"]').type('', {delay: 0}); - cy.get('form[id="customHeaderSettingsForm"] button:contains("OK")').click(); - cy.get('div:contains("Your changes have been saved.")'); + cy.get('tr[id="component-grid-settings-plugins-settingsplugingrid-category-generic-row-customheaderplugin"] a.show_extras').click(); + cy.get('a[id^="component-grid-settings-plugins-settingsplugingrid-category-generic-row-customheaderplugin-settings-button"]').click(); + cy.waitJQuery(2000); // Wait for form to settle + cy.get('textarea[id^="headerContent-"]').type('', {delay: 0}); + cy.get('textarea[id^="footerContent-"]').type('', {delay: 0}); + cy.get('form[id="customHeaderSettingsForm"] button:contains("OK")').click(); + cy.get('div:contains("Your changes have been saved.")'); - cy.visit(''); - cy.get('iframe[id*="twitter-widget"]'); - }); + cy.visit(''); + cy.get('iframe[id*="twitter-widget"]'); + }); }) From 4d954127fd855bacd1e2b845ac2ee2e07751e501 Mon Sep 17 00:00:00 2001 From: Kaitlin Newson Date: Fri, 25 Jul 2025 11:42:03 -0300 Subject: [PATCH 4/5] pkp/pkp-lib#10671 fix undefined constant --- CustomHeaderSettingsForm.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CustomHeaderSettingsForm.php b/CustomHeaderSettingsForm.php index 22229b8..f3164d1 100644 --- a/CustomHeaderSettingsForm.php +++ b/CustomHeaderSettingsForm.php @@ -17,6 +17,7 @@ use APP\notification\NotificationManager; use APP\template\TemplateManager; use PKP\form\Form; +use PKP\form\validation\FormValidator; use PKP\form\validation\FormValidatorCSRF; use PKP\form\validation\FormValidatorCustom; use PKP\form\validation\FormValidatorPost; @@ -36,7 +37,7 @@ public function __construct(CustomHeaderPlugin $plugin, int $contextId) parent::__construct($plugin->getTemplateResource('settingsForm.tpl')); - $this->addCheck(new FormValidatorCustom($this, 'backendContent', FORM_VALIDATOR_OPTIONAL_VALUE, 'plugins.generic.customHeader.backendContent.error', function ($backendContent) { + $this->addCheck(new FormValidatorCustom($this, 'backendContent', FormValidator::FORM_VALIDATOR_OPTIONAL_VALUE, 'plugins.generic.customHeader.backendContent.error', function ($backendContent) { return $this->validateWellFormed($backendContent); })); $this->addCheck(new FormValidatorPost($this)); From 3031840790f729a0cd7f4a39226d5370cce920d0 Mon Sep 17 00:00:00 2001 From: Kaitlin Newson Date: Fri, 25 Jul 2025 11:48:40 -0300 Subject: [PATCH 5/5] update test with new backend field --- cypress/tests/functional/CustomHeader.cy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/cypress/tests/functional/CustomHeader.cy.js b/cypress/tests/functional/CustomHeader.cy.js index 7fb53c3..f4c3ea9 100644 --- a/cypress/tests/functional/CustomHeader.cy.js +++ b/cypress/tests/functional/CustomHeader.cy.js @@ -26,6 +26,7 @@ describe('Custom Header plugin tests', function () { cy.waitJQuery(2000); // Wait for form to settle cy.get('textarea[id^="headerContent-"]').type('', {delay: 0}); cy.get('textarea[id^="footerContent-"]').type('', {delay: 0}); + cy.get('textarea[id^="backendContent-"]').type('Notice: this is a test', {delay: 0}); cy.get('form[id="customHeaderSettingsForm"] button:contains("OK")').click(); cy.get('div:contains("Your changes have been saved.")');