TYPO3 How to add Create new button on TCA? - php

I would like to build a slider (Own Content Element). So on the backend i would like to have a section with multiple records. What do i mean? By clicking the "Create new" i would like to have an image selection and rich text selection.
Something like that.
How can i achieve this?
So far i have:
TCA/Overrides/tt_content.php
which gives me the rich editor and the image selection in backend, but not grouped.
$GLOBALS['TCA']['tt_content']['types']['my_slider'] = array( 'showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.general;general,
--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.headers;headers,bodytext,assets;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.media,
',
'columnsOverrides' => [
'bodytext' => [
'config' => [
'enableRichtext' => true,
'richtextConfiguration' => 'default'
]
]
]
);
tt_content.typosript
tt_content {
my_slider < lib.contentElement
my_slider {
templateRootPaths.10 = {$Private}Templates/
templateName = Slider.html
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
10 {
references.fieldName = assets
as = images
}
}
}
}
Slider.html
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<h1>{data.header}</h1>
<p>{data.bodytext}</p>
<f:for each="{images}" as="image">
<f:image image="{image}" alt="{file.properties.alt}" cropVariant="desktop"/>
{image.description}
</f:for>
<f:debug>{data}</f:debug>
</html>
Now with the current code i get the results in frontend. One Text and one Image. But how can i get it as group after configured it on the backend?

You need add new field to the sys_file_reference TCA:
Configuration/TCA/Overrides/sys_file_reference.php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
'sys_file_reference',
[
'tx_myext_description' => [
'label' => 'My field description',
'config' => [
'type' => 'text',
'cols' => '80',
'rows' => '15',
'enableRichtext' => true,
'richtextConfiguration' => 'default'
]
],
]
);
ext_tables.sql
CREATE TABLE sys_file_reference (
tx_myext_description mediumtext,
);
Remember to add new field into database (using database compare tool in install tool).
Then use it in TCA of your new slider:
Configuration/TCA/Overrides/tt_content.php
$GLOBALS['TCA']['tt_content']['types']['my_slider'] = [
'showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.general;general,
--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.headers;headers,bodytext,assets;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.media,
',
'columnsOverrides' => [
'bodytext' => [
'config' => [
'enableRichtext' => true,
'richtextConfiguration' => 'default'
]
],
'assets' => [
'config' => [
'overrideChildTca' => [
'types' => [
0 => ['showitem' => $GLOBALS['TCA']['sys_file_reference']['types'][0]['showitem'].',tx_myext_description'],
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
'showitem' => $GLOBALS['TCA']['sys_file_reference']['types'][\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT]['showitem'].',tx_myext_description'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
'showitem' => $GLOBALS['TCA']['sys_file_reference']['types'][\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE]['showitem'].',tx_myext_description'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
'showitem' => $GLOBALS['TCA']['sys_file_reference']['types'][\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO]['showitem'].',tx_myext_description'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
'showitem' => $GLOBALS['TCA']['sys_file_reference']['types'][\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO]['showitem'].',tx_myext_description'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => $GLOBALS['TCA']['sys_file_reference']['types'][\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION]['showitem'].',tx_myext_description'
],
],
],
],
],
],
];
And then your Fluid template may look like that:
Slider.html
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<h1>{data.header}</h1>
<p>{data.bodytext}</p>
<f:for each="{images}" as="image">
<f:image image="{image}" alt="{file.properties.alt}" cropVariant="desktop"/>
{image.properties.tx_myext_description -> f:format.html()}
</f:for>
</html>

Related

TYPO3 BE TCA type Preview Image

i search for a Solution:
How can i add a Preview Image for a TCA type?
Example: I have 3 different types and would like to display a preview image for them. The same as the t3 backend layouts.
Just like the Backend-Layout:
Maybe there is a solution to this?
The documentation is explaining it:
https://docs.typo3.org/m/typo3/reference-tca/main/en-us/Columns/Examples.html#select-drop-down-for-records-represented-by-images
This is the example code:
[
'columns' => [
'select_single_12' => [
'label' => 'select_single_12 foreign_table selicon_field',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_styleguide_elements_select_single_12_foreign',
'fieldWizard' => [
'selectIcons' => [
'disabled' => false,
],
],
],
],
],
]
And the code for the field of the connected table is this:
[
'ctrl' => [
'title' => 'Form engine elements - select foreign single_12',
'label' => 'fal_1',
'selicon_field' => 'fal_1',
// ...
],
'columns' => [
// ...
'fal_1' => [
'label' => 'fal_1 selicon_field',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'fal_1',
[
'maxitems' => 1,
],
$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext']
),
],
],
// ...
];
As you have a strange label inside your field it's not clear if you want to link to an image, to a text or even to a field that offers a combination like it's done with relations to the table sys_file by the intermediate table sys_file_ref.
So defining more precise what you need exactly might help to give you a more detailed answer. You can edit your answer to add this description.

How to show users registered in last 6 months on charts in Laravel

I have used consoletvs/charts for showing the statistic of users registered in a year, but now I want to change it from "current year" to "last six months from the current date." I have extracted the last six months' data from the users' table, but I am stuck on displaying only the last six months on the chart.
statsController.php
public function index()
{
$users = User::whereBetween('created_at',
[Carbon::now()->subMonth(6), Carbon::now()]
)->get();
$chart = Charts::database($users, 'bar', 'highcharts')
->title("Users Joining Stats")
->elementLabel("Users Joined - Monthly")
->dimensions(700, 400)
->responsive(true)
->groupByMonth(date('Y'), true);
$pie = Charts::create('pie', 'highcharts')
->title('Freelancers & Employee %')
->labels(['Employers', 'Freelancers'])
->values([7, 92])
->dimensions(1000, 500)
->responsive(true);
return view('back-end.admin.stats.index', compact('chart', 'pie'));
}
index.blade.php
#extends(file_exists(resource_path('views/extend/back-end/master.blade.php')) ? 'extend.back-end.master' : 'back-end.master')
#section('content')
<section class="wt-haslayout wt-dbsectionspace" id="profile_settings">
<div >
<div >
<h2>Ebelong Statistics</h2>
<div >
<div >
<div >
{!! $chart->html() !!}
</div>
<hr>
{!!$pie->html() !!}
</div>
</div>
</div>
</div>
{!! Charts::scripts() !!}
{!! $chart->script() !!}
{!! $pie->script() !!}
</section>
#endsection
chart.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Default settings for charts.
|--------------------------------------------------------------------------
*/
'default' => [
'type' => 'line', // The default chart type.
'library' => 'material', // The default chart library.
'element_label' => 'Element', // The default chart element label.
'empty_dataset_label' => 'No Data Set',
'empty_dataset_value' => 0,
'title' => 'My Cool Chart', // Default chart title.
'height' => 400, // 0 Means it will take 100% of the division height.
'width' => 0, // 0 Means it will take 100% of the division width.
'responsive' => false, // Not recommended since all libraries have diferent sizes.
'background_color' => 'inherit', // The chart division background color.
'colors' => [], // Default chart colors if using no template is set.
'one_color' => false, // Only use the first color in all values.
'template' => 'material', // The default chart color template.
'legend' => true, // Whether to enable the chart legend (where applicable).
'x_axis_title' => false, // The title of the x-axis
'y_axis_title' => null, // The title of the y-axis (When set to null will use element_label value).
'loader' => [
'active' => true, // Determines the if loader is active by default.
'duration' => 500, // In milliseconds.
'color' => '#000000', // Determines the default loader color.
],
],
/*
|--------------------------------------------------------------------------
| All the color templates available for the charts.
|--------------------------------------------------------------------------
*/
'templates' => [
'material' => [
'#2196F3', '#F44336', '#FFC107',
],
'red-material' => [
'#B71C1C', '#F44336', '#E57373',
],
'indigo-material' => [
'#1A237E', '#3F51B5', '#7986CB',
],
'blue-material' => [
'#0D47A1', '#2196F3', '#64B5F6',
],
'teal-material' => [
'#004D40', '#009688', '#4DB6AC',
],
'green-material' => [
'#1B5E20', '#4CAF50', '#81C784',
],
'yellow-material' => [
'#F57F17', '#FFEB3B', '#FFF176',
],
'orange-material' => [
'#E65100', '#FF9800', '#FFB74D',
],
],
/*
|--------------------------------------------------------------------------
| Assets required by the libraries.
|--------------------------------------------------------------------------
*/
'assets' => [
'global' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js',
],
],
'canvas-gauges' => [
'scripts' => [
'https://cdn.rawgit.com/Mikhus/canvas-gauges/gh-pages/download/2.1.2/all/gauge.min.js',
],
],
'chartist' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/chartist/0.10.1/chartist.min.js',
],
'styles' => [
'https://cdnjs.cloudflare.com/ajax/libs/chartist/0.10.1/chartist.min.css',
],
],
'chartjs' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js',
],
],
'fusioncharts' => [
'scripts' => [
'https://static.fusioncharts.com/code/latest/fusioncharts.js',
'https://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js',
],
],
'google' => [
'scripts' => [
'https://www.google.com/jsapi',
'https://www.gstatic.com/charts/loader.js',
"google.charts.load('current', {'packages':['corechart', 'gauge', 'geochart', 'bar', 'line']})",
],
],
'highcharts' => [
'styles' => [
// The following CSS is not added due to color compatibility errors.
// 'https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/css/highcharts.css',
],
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/highcharts.js',
'https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.7/js/modules/offline-exporting.js',
'https://cdnjs.cloudflare.com/ajax/libs/highmaps/5.0.7/js/modules/map.js',
'https://cdnjs.cloudflare.com/ajax/libs/highmaps/5.0.7/js/modules/data.js',
'https://code.highcharts.com/mapdata/custom/world.js',
],
],
'justgage' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.6/raphael.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.2/justgage.min.js',
],
],
'morris' => [
'styles' => [
'https://cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css',
],
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.6/raphael.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js',
],
],
'plottablejs' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/plottable.js/2.8.0/plottable.min.js',
],
'styles' => [
'https://cdnjs.cloudflare.com/ajax/libs/plottable.js/2.2.0/plottable.css',
],
],
'progressbarjs' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/progressbar.js/1.0.1/progressbar.min.js',
],
],
'c3' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.js',
],
'styles' => [
'https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.css',
],
],
'echarts' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/echarts/3.6.2/echarts.min.js',
],
],
'amcharts' => [
'scripts' => [
'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.2/amcharts.js',
'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.2/serial.js',
'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.2/plugins/export/export.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.2/themes/light.js',
],
'styles' => [
'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.2/plugins/export/export.css',
],
],
],
];
One way to do this is to aggregate the count on a monthly base an pass the data to the chart:
$data = [];
foreach (range(0, 6) as $i) {
$date = now()->subMonths($i);
$dates[$date->format('m')] = User::query()
->where('created_at', '>=', $date->startOfMonth()->startOfDay()->toDateString())
->where('created_at', '<=', $date->endOfMonth()->endOfDay()->toDateString())
->count();
}
$data = array_reverse($data);
You can access the chart labels with array_keys($data), and the values with array_values($data).
Please also take note to use the Eloquent count() method instead of get() as you don't need the fully loaded model.

Add TYPO3 palette to all elements?

I have made a custom palette in tt_content.php and want to add it to all content elements on the appearance tab like this:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'tt_content',
'--palette--;My Palette;my_palette',
'',
'before:sectionIndex'
);
This works for everything except Grid Elements (gridelements_pi1). How do I make the new palette show up on Grid Elements as well?
The comment from #MathiasBrodala lead me to finding the answer is in the order of extensions.
In this case I needed to add gridelements under suggests in my ext_emconf.php which ensures it will be loaded before my site package.
$EM_CONF[$_EXTKEY] = [
'title' => 'My Package',
'description' => 'TYPO3 Sitepackage',
'category' => 'templates',
'version' => '1.0.0',
'state' => 'stable',
'constraints' => [
'depends' => [
'typo3' => '8.7.0-9.5.99',
'fluid_styled_content' => '8.7.0-9.5.99'
],
'suggests' => [
'gridelements' => '9.3.0-0.0.0',
],
'conflicts' => [
],
],
'uploadfolder' => 0,
'createDirs' => '',
'clearCacheOnLoad' => 1
];

Populate label or attribute of form element in Zend Framework 3

I'm still fairly new to ZF3 so forgive me if I'm asking an obvious question here, but after many searches, looks through the source and head scratching, I can't seem to find an obvious approach to populating label text with data from the entity.
Basically, I have a form collection containing form elements which are each stored with a type (ID), e.g. "Business phone", "Mobile phone", etc.
Is there a way to populate anything other than a value in a form element?
Edit (more info)
So, there is a PersonForm, with a Person Fieldset which contains a Phone Fieldset collection:
$phoneFieldset = new PhoneFieldset($objectManager);
$this->add([
"type" => Element\Collection::class,
"name" => "Phones",
"options" => [
"count" => 0,
"should_create_template" => true,
"allow_add" => true,
"allow_remove" => true,
"target_element" => $phoneFieldset
],
]);
This Phone fieldset contains the following elements:
$this->add([
"name" => "Type_ID",
"type" => "hidden",
]);
$this->add([
"name" => "Number",
"type" => "text",
"attributes" => [
"placeholder" => "Enter phone number",
],
"options" => [
"label" => "Email" // Ideally this would be $entity->getTypeName() for example, which would return the name based on the Type_ID mapped against a constant
]
]);
Sure, adding label information for a formCollection (Fieldset or Collection elements) is pretty much the same as for input elements (Element) (Element docs).
Some examples:
Add a Fieldset into a Form ($this->formCollection($form->get('address'))):
Docs: https://docs.zendframework.com/zend-form/element/collection/
$this->add(
[
'type' => AddressFieldset::class, // Note: FQCN -> provided by FormElementManager
'name' => 'address',
'required' => true,
'options' => [
'use_as_base_fieldset' => false,
'label' => _('Address'),
'label_options' => [
// .. add options for the label, see LabelInterface
],
'label_attributes' => [
// .. add attributes for the label, see LabelInterface
],
],
]
);
Renders as:
<fieldset>
<legend>Address</legend>
<!-- the inputs / labels of `Element` objects -->
</fieldset>
Add a Collection into a Form ($this->formCollection($form->get('cities'))):
Docs: https://docs.zendframework.com/zend-form/element/collection/
$this->add(
[
'name' => 'cities',
'type' => Collection::class,
'options' => [
'label' => _('Cities'),
'should_create_template' => true,
'allow_add' => true,
'allow_remove' => true,
'count' => 1,
'target_element' => $this->getCityFieldset(), // Must be an instantiated Fieldset (so provide via Factory)
'label_options' => [
// .. add options for the label, see LabelInterface
],
'label_attributes' => [
// .. add attributes for the label, see LabelInterface
],
],
'attributes' => [
'class' => 'fieldset-collection',
'data-fieldset-name' => _('City'),
],
]
);
Renders as:
<fieldset class="fieldset-collection" data-fieldset-name="City">
<legend>Cities</legend>
<fieldset><!-- add a <legend> using JS here, with the data-fieldset-name of the parent -->
<!-- the inputs / labels of `Element` objects -->
</fieldset>
<span data-template="<!-- contains entire template so you can use JS to create 'add' and 'remove' buttons for additional CityFieldset <fieldset> elements -->"></span>
</fieldset>
I added in the <!-- comments --> in the HTML output, you can figure those out ;-)
Additionally, if you're using an ORM, Doctrine in this example, then you could do it like this:
$this->add(
[
'name' => 'roles',
'required' => true,
'type' => ObjectMultiCheckbox::class,
'options' => [
'object_manager' => $this->getObjectManager(),
'target_class' => Role::class,
'property' => 'id',
'label' => _('Roles'),
'label_generator' => function ($targetEntity) {
/** #var Role $targetEntity */
return $targetEntity->getName();
},
'label_options' => [
'label_position' => FormRow::LABEL_APPEND,
],
'use_hidden_element' => true,
'checked_value' => 1,
'unchecked_value' => 0,
],
'attributes' => [
'class' => 'form-check-input',
],
]
);
Doctrine Form Elements docs

TYPO3 how to add virtual column to the TCA?

how can I add an virtual column to the TCA (TYPO3 8)? I have in a 1:n table with data and I want to display the count of the data in the backend to current element.
I need something like this:
$fields = [
'counts7d' => [
'exclude' => false,
'label' => 'last 7 days',
'config' => [
'type' => 'none',
'procFunc' => '\Namespace\MyClass->MyMethod',
'readOnly' => true,
'params' => [
'period => '7d'
]
]
],
'counts30d' => [
'exclude' => false,
'label' => 'last 30 days',
'config' => [
'type' => 'none',
'procFunc' => '\Namespace\MyClass->MyMethod',
'readOnly' => true,
'params' => [
'period => '30d'
]
]
],
];
pseudo function:
public function myMethod($element, $params){
$sql = "SELECT count(*) FROM TABLE WHERE pid=$element[uid] and date > $params[period]";
return sql_count…
}
The field should only be informative for the backend users.
Does anyone have an idea?
Thanks
Oliver
The TCA field type user is exactly what you are looking for:
'counts7d' => [
'exclude' => false,
'label' => 'last 7 days',
'config' => [
'type' => 'user',
'userFunc' => \Namespace\MyClass::class . '->MyMethod',
'parameters' => [
'period => '7d',
],
],
],
The TCA field type none is exactly what you are looking for. Type none is the only type that does not necessarily need a database field. To manipulate it you can use userFunc which allow you to use custom php function.

Categories