TYPO3 hook for saving page settings - typo3

I'm searching for a hook which is called after page settings saving or change. I tried this answer TYPO3: Hook after creating or editing page, but it does something else.
Does someone know of one?

I was solving this problem a week ago. You have to have a class ProcessCmdmap in folder Extension/Classes/Hooks/ProcessCmdmap.php which is called by hook, and this class should have a method which is called by the save. I recommend this method processDatamap_postProcessFieldArray
<?php
namespace Vendor\Extension\Hooks;
class ProcessCmdmap {
public function processDatamap_postProcessFieldArray($status, $table, $id, array &$fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
var_dump($id);
var_dump($table);
var_dump($status);
var_dump($fieldArray);
var_dump($pObj);
}
}
?>
And dont forget to register your hook:
$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][''] = 'Vendor\Extension\Hooks\ProcessCmdmap';
$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'][''] = 'Vendor\ Extension\Hooks\ProcessCmdmap';

Related

Create CSS classes based on user role

Working with Moodle 3.9 and a fork of the current Academi theme.
I am trying to create a css class hook on the <body> element which is based on the user's role(s). I understand that a user's role(s) are context-driven, (maybe a student in one course, and something else in another), so I would output all the roles as classes for a given context.
Based on some extensive digging on the moodle forum I have the following:
// User role based CSS classes
global $USER, $PAGE;
$context = context_system::instance();
$roles = get_user_roles($context, $USER->id, true);
if(is_array($roles)) {
foreach($roles as $role) {
$PAGE->add_body_class('role-'.$role->shortname);
}
} else {
$PAGE->add_body_class('role-none');
}
Preferably I'd like this to run on every page. From within the theme, I've tried just placing this in just about every location/function I thought could be executed early enough to modify the body element. Either I get no output at all or a warning indicating that it is too late to run add_body_class().
I've had a skim of the Page and Output APIs and I still don't have a sense of how or when to execute this code. Should this be a custom plugin instead?
Override the header() function on the core renderer of your current theme template, for instance, on theme\YOUR_THEME\classes\output\core_renderer.php:
namespace theme_YOUR_THEME\output;
defined('MOODLE_INTERNAL') || die;
use context_system;
class core_renderer extends \theme_boost\output\core_renderer {
public function header() {
global $USER;
$roles = get_user_roles(context_system::instance(),$USER->id);
if (is_array($roles) && !empty($roles)){
foreach($roles as $role){
$this->page->add_body_class('role-'.$role->shortname);
}
}else{
$this->page->add_body_class('role-none');
}
return parent::header();
}
}
This way, every page would call this function and have the desired css classes added to the body tag.

yii2 ActiveForm without begin form tag

I need to generate widgets\ActiveForm::field() without "form" tag at begin. I looked in source of yii\widgets\ActiveForm and found that this can not be avoided :(
public function init()
{
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
echo Html::beginForm($this->action, $this->method, $this->options);
}
Maybe there's another way to solve this problem without extending the 'ActiveForm' class?
ActiveField is basically just a wrapper for yii\helpers\Html::active... methods so you just can call echo yii\helpers\Html::activeTextInput($model, $attribute, $options); without using ActiveForm

Customize Editview in Custom Safe Manner

Is there a way to customize module(Eg:Contacts) in an custom safe manner.
My requirement is too load one javascript in editview of Contacts module.
I have currently called the js in custom/modules/Contacts/views/view.edit.php and have created an addon for same.
But when I will upload the addon , if that file custom/modules/Contacts/views/view.edit.php already present will be overridden.
Is there an other way to do the same which do not removes customizations?
You can do the following:
<?php
require_once("modules/Contacts/views/view.edit.php");
class CustomContactsViewEdit extends ContactsViewEdit
{
public function __construct(){
parent::__construct();
}
public function display(){
parent::display();
//Load your javascript file here
}
}
OR You can include your javascript file on the editviewdefs metadata.
$viewdefs['Contacts']['EditView]['templateMeta']['includes][] = array(
'file' => 'custom/modules/Contacts/CustomJs.js',
);
Havent checked this code but it will surely work.

Zend_Form::setAction() uses current controller in Zend Framework

I declare a publisher controller:
class PublisherController extends Zend_Controller_Action {
public function indexAction()
{
$this->view->form = $this->_getForm();
$this->render('form');
}
public function dataPostAction()
{
//#TODO
}
protected function _getForm()
{
$form = new Zend_Form();
$form->setAction('publisher/dataPost')//Here, I DO NOT want to do: setAction('*/dataPost') with `*` means current controller.
->setMethod('post')
->setAttrib('id','publisher-form');
$form->addElement('text', 'name',
array(
'label'=>'First Name',
'class'=>'required'
)
);
$form->addElement('submit', 'Save');
return $form;
}
}
Look at the line: $form->setAction('publisher/dataPost')
This means that I want to set the action for the form after submitting is dataPost of publisher controller.
Now I want do do $form->setAction('*/dataPost') with the * means current controller. Because current controller is publisher too.
But it does not work, or am I missing something? Can you tell me what is correct?
publisher/dataPost is much easier to type than $form->setAction($this->getRequest()->getControllerName().'/dataPost'), so I would recommend you stick with what you are already doing.
I don't normally use it in the zend form its self, but preferably in the actions view when calling the form using this code.
<?php echo $this->setAction(url(/.../.../) );?>
This is to echo the form you using in your action and also to set its action. So in short just stick to what you have or use sam's method but I think its better if you have something ACCURATE and working.
I decide the comment of #Sam is the best answer for me.
Using the statement:
$form->setAction($this->getRequest()->getControllerName().'/dataPost')
UPDATE
From this question, I know that: "DO NOT be complex", and some guys here is don't agree so much with the above solution. Now I got this too. But, for this answer, I believe that I SHOULD check and confirm what is correct.

ZEND Controllers -- How to call an action from a different controller

I want to display a page that has 2 forms. The top form is unique to this page, but the bottom form can already be rendered from a different controller. I'm using the following code to call the action of the other form but keep getting this error:
"Message: id is not specified"
#0 .../library/Zend/Controller/Router/Rewrite.php(441): Zend_Controller_Router_Route->assemble(Array, true, true)
My code:
First controller:
abc_Controller
public function someAction()
{
$this->_helper->actionStack('other','xyz');
}
Second controller:
xyz_Controller
public function otherAction()
{
// code
}
Desired results:
When calling /abc/some, i want to render the "some" content along with the xyz/other content. I think I followed the doc correctly (http://framework.zend.com/manual/en/zend.controller.actionhelpers.html) but can't find any help on why that error occurs. When I trace the code (using XDebug), the xyz/other action completes ok but when the abc/some action reaches the end, the error is thrown somewhere during the dispatch or the routing.
Any help is greatly appreciated.
You can accomplish this in your phtml for your someAction. So in some.phtml put <?php echo $this->action('other','xyz');?> this will render the form found in the otherAction of XyzController
The urge to do something like this is an indication you're going about it in totally the wrong way. If you have the urge to re-use content, it should likely belong in the model. If it is truly controller code it should be encapsulated by an action controller plugin
In phtml file u can use the $this->action() ; to render the page and that response would be added to current response ..
The syntax for action is as follows::
public function action($action, $controller, $module = null, array $params = array())
You can create new object with second controller and call its method (but it`s not the best way).
You can extend your first controller with the second one and call $this->methodFromSecond(); - it will render second form too with its template.
BTW - what type of code you want to execute in both controllers ?
Just an update. The error had absolutely nothing to do with how the action was being called from the second controller. It turns out that in the layout of the second controller, there was a separate phtml call that was throwing the error (layout/abc.phtml):
<?php echo $this->render('userNavigation.phtml') ?>
line of error:
echo $this->navigation()->menu()->renderMenu(...)
I'll be debugging this separately as not to muddy this thread.
Thanks to Akeem and hsz for the prompt response. I learned from your responses.
To summarize, there were 3 different ways to call an action from an external controller:
Instantiate the second controller from the first controller and call the action.
Use $this->_helper->actionStack
In the phtml of the first controller, action('other','xyz');?> (as Akeem pointed out above)
Hope this helps other Zend noobs out there.
Hm I can't find and idea why you need to use diffrent Controlers for one view. Better practise is to have all in one Controller. I using this like in this example
DemoController extends My_Controller_Action() {
....
public function indexAction() {
$this->view->oForm = new Form_Registration();
}
}
My_Controller_Action extends Zend_Controller_Action() {
public function init() {
parent::init();
$this->setGeneralStuf();
}
public function setGeneralStuf() {
$this->view->oLoginForm = new Form_Login();
}
}
This kind of route definition:
routes.abc.route = "abc/buy/:id/*"
routes.abc.defaults.controller = "deal"
routes.abc.defaults.action = "buy"
routes.abc.reqs.id = "\d+"
requires a parameter in order to function. You can do this with actionStack but you can also specify a default id in case that none is provided:
$this->_helper->actionStack('Action',
'Controller',
'Route',
array('param' => 'value')
);
routes.abc.defaults.id = "1"
For Me this worked like a charm
class abcController extends Zend_Controller_Action
{
public function dashBoardAction()
{
$this->_helper->actionStack('list-User-Data', 'xyz');
}
}
class XyzController extends Zend_Controller_Action {
public function listUserDataAction()
{
$data = array('red','green','blue','yellow');
return $data;
}
}