I'm searching for a hook which is called after page creation or changes on pages like "hide page in nav", "deactivate page" or "move/delete page"
Does someone know of one?
Thanks!
These Hooks are located in t3lib/class.t3lib_tcemain.php
The following are just some of those:
processDatamap_preProcessFieldArray
processDatamap_postProcessFieldArray
hook_processDatamap_afterDatabaseOperations
processDatamap_afterAllOperations
In your case, i think you could use "processDatamap_postProcessFieldArray".
Example how to include it in your ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = 'EXT:your_extension/hooks/class.tx_yourextension_tcemain.php:tx_yourextension_tcemain';
Example class:
<?php
class tx_yourextension_tcemain {
function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray, &$pObj) {
if($table == 'pages' && $status =='new') {
// do some stuff
}
}
}
?>
With $table, you can check which table is modified. $status allows you to retrieve the current action, for example "new", "update" or "delete".
Example for TYPO3 > 6 with namespaces on another hook:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages']['YourExtension\\Hook\\FilterMenuPages'] = 'EXT:your_extension/Classes/Hook/FilterMenuPages.php:YourExtension\Hook\FilterMenuPages';
For TYPO3 7.6 version (Also Works in 10.4.X as well)
Write following in ext_localconf.php
$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['extkey'] = 'Vendor\\Extension\\Hook\\TCEmainHook';
$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['extkey'] = 'Vendor\\Extension\\Hook\\TCEmainHook';
Create hook class /Classes/Hook/TCEmainHook.php, Choose appropriate function from below list
<?php
namespace Vendor\Extension\Hook;
class TCEmainHook {
public function processCmdmap_preProcess($command, $table, $id, $value, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
public function processCmdmap_postProcess($command, $table, $id, $value, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
public function processDatamap_preProcessFieldArray(array &$fieldArray, $table, $id, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
public function processCmdmap_deleteAction($table, $id, $recordToDelete, $recordWasDeleted=NULL, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
public function processDatamap_afterAllOperations(\TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
public function processDatamap_postProcessFieldArray($status, $table, $id, array &$fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
public function processDatamap_afterDatabaseOperations($status, $table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {}
}
There is a extension dmc_hooklist which list all hooks. (used a few years ago)
Or have an look into t3lib/class.t3lib_tcemain.php there are the hooks you need.
Related
I'm having a problem with my controller, when I try to call request->isAJAX() the program returns the error undefined method
Note : i'm using codeigniter 4.1.1
<?php
namespace App\Controllers;
use App\Models\Mruang;
class Ruang extends BaseController
{
protected $jenis;
public function __construct()
{
$this->jenis = new Mruang();
}
public function index()
{
$data = [
'titel' => 'Jenis Ruang'
];
return view('ruang/index', $data);
}
public function tampil()
{
if ($this->request->isAJAX()) {
$data = [
'ruang' => $this->jenis->findAll(),
'btn' => true
];
$msg = [
'data' => view('ruang/data', $data)
];
echo json_encode($msg);
}
}
}
I run your code at my local machine in a CI 4.1.1 installation and it runs ok, at least the $this->request->isAJAX() worked as expected.
Look at your BaseController and compare it with the default. I pasting the default code bellow
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class BaseController extends Controller
{
protected $helpers = [];
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
}
}
I also would like to recommend you to look if Mruang model has the findAll() methods.
I am using Maatwebsite / laravel to export data , I need to rename the Worksheet ,
below my class :
<?php
namespace App\Exports;
use App\Models\Client;
use App\Models\Item;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
class ItemExport implements FromCollection, WithHeadings, ShouldAutoSize
{
protected $rows;
use Exportable;
public function __construct($client_id , $items , $company_name)
{
$this->client_id = $client_id;
$this->items = $items;
$this->company_name = $company_name;
}
public function collection()
{
$i = 1;
$client = Client::find($this->client_id);
$item_new= [];
foreach($this->items as $item){
$item_new[] = [$i++,
$this->company_name,
$this->item,
$client->client_name,
];
}
return collect($item_new);
}
public function title(): string
{
return $this->company_name;
}
public function headings(): array
{
return [
'#',
'Company',
'item',
'client',
];
}
}
but it seems the public function title(): string , not working .
i supposed that the title function will work , but seems no
any idea how to give name to Worksheet ?
thanks
So close. You just need to implement the WithTitle interface.
class ItemExport implements FromCollection, WithHeadings, WithTitle, ShouldAutoSize
An example is somewhat buried in the multiple sheets section of the documentation, but I can confirm it works for single sheets too.
https://docs.laravel-excel.com/3.1/exports/multiple-sheets.html#sheet-classes
Laravel-How to create multiple sheet in one excel file using maatwebsite/excel": "^3.1.
1st step: I created a multiple excel export file
php artisan make:export MultipleSheetExport
2nd Create a route and controller
In controller I have written this function
public function state_summary_export()
{
return Excel::download(new MultipleSheetExport, 'ADCC Summary.xlsx');
}
Note: 'ADCC Summary.xlsx' is my excel file name.
Don’t forget to add this facades in you controller
use App\Exports\MultipleSheetExport;
use Maatwebsite\Excel\Facades\Excel;
3rd step: Open MultipleSheetExport
<?php
namespace App\Exports;
use Illuminate\Support\Arr;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithTitle;
class MultipleSheetExport implements WithMultipleSheets
{
public function sheets(): array
{
$sheets = [
new StateSummaryExport(),
new BMRPerformanceExport(),
];
return $sheets;
}
}
4th step: Go to Child StateSummaryExport and add this given line.
class StateSummaryExport implements WithTitle
public function title(): string
{
return 'State Summary';
}
Note: ‘State Summary’ is your sheet name. Do the same in BMRPerformanceExport.
Thank you.
I get tutorial from here : https://laravel-excel.maatwebsite.nl/docs/3.0/export/basics
<?php
...
use App\Exports\ItemsDetailsExport;
class ItemController extends Controller
{
...
public function exportToExcel(ItemsDetailsExport $exporter, $id)
{
//dd($id); I get the result
return $exporter->download('Summary Detail.xlsx');
}
}
My export like this :
<?php
namespace App\Exports;
use App\Repositories\Backend\ItemDetailRepository;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Support\Facades\Input;
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
public function __construct(ItemDetailRepository $itemDetailRepository)
{
$this->itemDetailRepository = $itemDetailRepository;
}
public function collection()
{
$test = Input::get('id');
dd('yeah', $test);
}
}
I want to pass id parameter to export file. I try like that, but I don't get the id. The id is null
How can I solve this problem?
For passing data from controller to laravel excel function we can pass and use data like below
For example, we have to pass data year like 2019 we will pass like below
in controller
Excel::download(new UsersExport(2019), 'users.xlsx');
In laravel import file
class UsersExport implements FromCollection {
private $year;
public function __construct(int $year)
{
$this->year = $year;
}
public function collection()
{
return Users::whereYear('created_at', $this->year)->get();
}
}
you can refer all following official documentation link
https://docs.laravel-excel.com/3.1/architecture/objects.html#plain-old-php-object
Unfortunately you can't use normal dependency injection when you have a specific parameter. This is what you can do though:
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
protected $id;
public function __construct(ItemDetailRepository $itemDetailRepository, $id)
{
$this->itemDetailRepository = $itemDetailRepository;
$this->id = $id;
}
public function collection()
{
$test = $this->id;
dd('yeah', $test);
}
}
Now the problem is that the container doesn't know how to resolve $id however there are two ways around this.
Manual passing of $id:
public function exportToExcel($id)
{
$exporter = app()->makeWith(ItemsDetailsExport::class, compact('id'));
return $exporter->download('Summary Detail.xlsx');
}
Route injection:
Define your route as:
Route::get('/path/to/export/{itemExport}', 'ItemController#exportToExcel');
In your RouteServiceProvider.php:
public function boot() {
parent::boot();
//Bindings
Route::bind('itemExport', function ($id) { //itemExport must match the {itemExport} name in the route definition
return app()->makeWith(ItemsDetailsExport::class, compact('id'));
});
}
Then your route method is simplified as:
public function exportToExcel(ItemsDetailsExport $itemExport)
{
//It will be injected based on the parameter you pass to the route
return $itemExport->download('Summary Detail.xlsx');
}
I've got a simple model (simplified of source):
class Collection
{
public $page;
public $limit;
}
And a form type:
class CollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('page', 'integer');
$builder->add('limit', 'integer');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'FSC\Common\Rest\Form\Model\Collection',
));
}
}
My controller:
public function getUsersAction(Request $request)
{
$collection = new Collection();
$collection->page = 1;
$collection->limit = 10;
$form = $this->createForm(new CollectionType(), $collection)
$form->bind($request);
print_r($collection);exit;
}
When i POST /users/?form[page]=2&form[limit]=20, the response is what i expect:
Collection Object
(
[page:public] => 2
[limit:public] => 20
)
Now, when i POST /users/?form[page]=3, the response is:
Collection Object
(
[page:public] => 3
[limit:public] =>
)
limit becomes null, because it was not submitted.
I wanted to get
Collection Object
(
[page:public] => 3
[limit:public] => 10 // The default value, set before the bind
)
Question: How can i change the form behaviour, so that it ignores non submitted values ?
If is only a problem of parameters (GET parameters) you can define the default value into routing file
route_name:
pattern: /users/?form[page]={page}&form[limit]={limit}
defaults: { _controller: CompanyNameBundleName:ControllerName:ActionName,
limit:10 }
An alternative way could be to use a hook (i.e. PRE_BIND) and update manually that value into this event. In that way you haven't the "logic" spreaded into multi pieces of code.
Final code - suggested by Adrien - will be
<?php
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
class IgnoreNonSubmittedFieldSubscriber implements EventSubscriberInterface
{
private $factory;
public function __construct(FormFactoryInterface $factory)
{
$this->factory = $factory;
}
public static function getSubscribedEvents()
{
return array(FormEvents::PRE_BIND => 'preBind');
}
public function preBind(FormEvent $event)
{
$submittedData = $event->getData();
$form = $event->getForm();
// We remove every child that has no data to bind, to avoid "overriding" the form default data
foreach ($form->all() as $name => $child) {
if (!isset($submittedData[$name])) {
$form->remove($name);
}
}
}
}
Here's a modification of the original answer. The most important benefit of this solution is that validators can now behave as if the form post would always be complete, which means there's no problems with error bubbling and such.
Note that object field names must be identical to form field names for this code to work.
<?php
namespace Acme\DemoBundle\Form;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
class FillNonSubmittedFieldsWithDefaultsSubscriber implements EventSubscriberInterface
{
private $factory;
public function __construct(FormFactoryInterface $factory)
{
$this->factory = $factory;
}
public static function getSubscribedEvents()
{
return array(FormEvents::PRE_BIND => 'preBind');
}
public function preBind(FormEvent $event)
{
$submittedData = $event->getData();
$form = $event->getForm();
// We complete partial submitted data by inserting default values from object
foreach ($form->all() as $name => $child) {
if (!isset($submittedData[$name])) {
$obj = $form->getData();
$getter = "get".ucfirst($name);
$submittedData[$name] = $obj->$getter();
}
}
$event->setData($submittedData);
}
}
I'm trying to learn the framework kohana.
I have defined a new controller under application/controller/classes. Which I named to hello.php:
class Controller_Hello extends Controller
{
public function action_say(){
$g = new View('firstv');
$g->render(TRUE);
}
}
?>
And I have this under application/views. Which I called firstv.php:
<h1>testing1</h1>
What's the mistake here. I'm using this guide:
http://pixelpeter.com/kohana/kohana101.pdf
I'm using the latest stable version 3.1.3.1. I have called the function by navigating to:
http://localhost/kohana/index.php/hello/say
Tried this using the same say function. And it worked. But this one doesn't use views.
$this->response->body('hello, world 2!');
Please help, thanks.
$this->response->body($g->render());
So your complete action method will be something like:
public function action_say()
{
$g = new View('firstv');
$this->response->body($g->render());
}
or:
public function action_say()
{
$g = new View('firstv');
$this->response->body($g);
}
or even:
public function action_say()
{
$this->response->body(new View('firstv'));
}