TYPO3 8.7 Extbase generate csv-file - typo3

I try to generate a csv-file in my TYPO3 Extension. I get following error:
1225709595: The Fluid template files "" could not be loaded. (More information)
TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException thrown in file
/usr/local/www/apache24/xx/xx/vendor/typo3fluid/fluid/src/View/TemplatePaths.php in line 719.
25 TYPO3Fluid\Fluid\View\TemplatePaths::resolveFileInPaths(array, "Default", "csv")
My Controller looks like:
$icalView = $this->objectManager->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView');
$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
$icalView->setFormat('csv');
$icalView->setTemplatePathAndFilename('typo3conf/ext/xxx/Resources/Private/Templates/Bestellung/Listbestellungen.txt');
$icalView->assign('xx', $xx);
$icalContent = $icalView->render();
I do have Subfolter "Layout" in ... Bestellung/ and I do have file Default.csv
Same code working in extension in TYPO3 7.6.x - what has changed in 8.7?
Thanks for help!
Martin

Here an snippet how I do it in 8.7 to send an eMail:
As I know you have to set the paths for Template, Layout and Partials also, before you select the template to use
/**
* configurationManager
*
* #var \TYPO3\CMS\Extbase\Configuration\ConfigurationManager
* #inject
*/
protected $configurationManager;
public function sendEmail($template,...)
{
/**
* Generate Email Body
*/
$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
/** #var StandaloneView $emailView */
$emailView = $this->objectManager->get(StandaloneView::class);
$emailView->getRequest()->setControllerExtensionName($controllerExtensionName);
$emailView->getRequest()->setPluginName($pluginName);
$emailView->getRequest()->setControllerName($controllerName);
$emailView->setTemplateRootPaths($extbaseFrameworkConfiguration['view']['templateRootPaths']);
$emailView->setLayoutRootPaths($extbaseFrameworkConfiguration['view']['layoutRootPaths']);
$emailView->setPartialRootPaths($extbaseFrameworkConfiguration['view']['partialRootPaths']);
$emailView->setTemplate('Email/' . ucfirst($template));
$emailView->assignMultiple($variables);
$emailBody = $emailView->render();
}

I solved this by changing the code a little bit and now it is working:
$storage = $this->resourceFactory->getDefaultStorage();
if ($storage === NULL) {
throw new \RuntimeException('Could not get the default storage', 1475590001);
}
/** #var \TYPO3\CMS\Fluid\View\StandaloneView $icalView */
$icalView = $this->objectManager->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView');
$icalView->setFormat('csv');
$templateRootPath[] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:xxx/Resources/Private/Templates/');
$layoutRootPaths[] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:xxx/Resources/Private/Layouts/');
$partialRootPaths[] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:xxx/Resources/Private/Partials/');
$icalView->setLayoutRootPaths($layoutRootPaths);
$icalView->setPartialRootPaths($partialRootPaths);
$icalView->setTemplatePathAndFilename('typo3conf/ext/xxx/Resources/Private/Templates/Bestellung/Listbestellungen.txt');
$icalView->assign('xxx', $xxx);
$icalContent = $icalView->render();
$tempFolder = $storage->getFolder('bestellungencsv');
$tempFile = $storage->createFile('bestellungen_'.$xxx->getUid().'.csv', $tempFolder);
$tempFile->setContents($icalContent);

Related

Set content-type HTTP header for 404 page in TYPO3 9.5

I am making a webservice using TYPO3. Everything in the frontend should be JSON with HTTP header Content-Type: application/json, however I am unable to change the Content-Type header for the 404 page. Whatever I try, it's always Content-Type: text/html; charset=utf-8. How can I change this?
This is my basic page TypoScript configuration:
page = PAGE
page {
config {
disableAllHeaderCode = 1
disablePrefixComment = 1
xhtml_cleaning = 0
admPanel = 0
}
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = MyExt
pluginName = MyPlugin
vendorName = MyVendor
}
}
The extension uses TYPO3\CMS\Extbase\Mvc\View\JsonView.
I've already tried adding the header using config.additionalHeaders.10.header = Content-Type: application/json. I've also tried setting [FE][pageNotFound_handling] to USER_FUNCTION:... and setting the headers in PHP.
I found the solution myself. From TYPO3 9.5 the default page not found handling can be overridden in the site configuration:
errorHandling:
-
errorCode: 404
errorHandler: PHP
errorPhpClassFQCN: Vendor\MyExt\PageErrorHandler\PageNotFoundHandler
And in EXT:MyExt/Classes/PageErrorHandler/PageNotFoundHandler.php:
<?php
namespace Vendor\MyExt\PageErrorHandler;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
/**
* Class PageNotFoundHandler
*/
class PageNotFoundHandler implements PageErrorHandlerInterface
{
/**
* Handle page error
*
* #param ServerRequestInterface $request
* #param string $message
* #param array $reasons
* #return ResponseInterface
*/
public function handlePageError(ServerRequestInterface $request, string $message, array $reasons = []): ResponseInterface
{
$response = new Response(404, ['Content-Type' => 'application/json'], '{"error":"Not found"}');
return $response;
}
}

codeignither HMVC version 3.0.6 view not loading

The follwing below is an controller for an template i am making in codeignither HMVC. I am trying to load this template module in my task modules but for some reason it wont load in the template modules but the data loads in my task controller.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class templates extends MX_Controller
{
/**
* Index Page for this controller.
*
* Maps to the following URL
* http://example.com/index.php/welcome
* - or -
* http://example.com/index.php/welcome/index
* - or -
* Since this controller is set as the default controller in
* config/routes.php, it's displayed at http://example.com/
*
* So any other public methods not prefixed with an underscore will
* map to /index.php/welcome/<method_name>
* #see https://codeigniter.com/user_guide/general/urls.html
*/
public function one_col($data)
{
$this->load->view('one_col',$data);
}
public function two_col($data)
{
$this->load->view('two_col',$data);
}
public function admin($data)
{
$this->load->view('admin', $data);
}
public function index()
{
echo "Hello world";
}
}
this code below is my task controller and it works fine when i run it in the link http://localhost:81/hmvc/index.php/tasks however when i try to run the template view "two_col" http://localhost:81/hmvc/index.php/templates/two_col
using this code in the template
<?php $this->load->view($module.'/'.$view_file); ?>
i get this error :
task module controller below
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class tasks extends MX_Controller
{
/**
* Index Page for this controller.
*
* Maps to the following URL
* http://example.com/index.php/welcome
* - or -
* http://example.com/index.php/welcome/index
* - or -
* Since this controller is set as the default controller in
* config/routes.php, it's displayed at http://example.com/
*
* So any other public methods not prefixed with an underscore will
* map to /index.php/welcome/<method_name>
* #see https://codeigniter.com/user_guide/general/urls.html
*/
public function index()
{
$this->load->model('mdl_tasks');
$data['query'] = $this->mdl_tasks->get('priority');
#$this->load->view('display', $data);
$data['view_file'] = "display";
$data['module'] = "tasks";
echo Modules::run('templates/two_col', $data);
#$this->load->module('templates');
#$this->templates->two_col($data);
}
}
echo Modules::run('templates/two_col', $data);
#$this->load->module('templates');
I'm pretty sure replacement these codes together will work.
Because php is an interpreted programming language. PHP loads every line one by one if deteced an error for ex. on 5Th line it doesnt compile the rest of lines. More information for interpreted lang. and also in your code you implementing the lib function before loading lib

doctrine migrations bundle and postgres schema: diff does not work properly

I'm using doctrine in my Symfony project, by connecting to an already existent postgres database.
The DB has several schemas, but the symfony app will use nothing but its own schema. The first Entity class I created is the following one:
namespace Belka\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="app_auth.User", schema="app_auth")
*/
class User {
/**
* #ORM\Column(type="string")
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $username;
/**
* #ORM\Column(type="string")
*/
private $email;
/**
* #ORM\Column(type="string")
*/
private $password;
}
as you can see, the Entity is specifying its own schema app_auth.
Next, I tried to use the migrations bundle. So, I installed and configured it, in order not to consider anything but my schema:
Extract of config.yml:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
schema_filter: ~^app_auth\..*~
Extract of config_dev.yml:
doctrine_migrations:
dir_name: "%kernel.root_dir%/../.container/update/DoctrineMigrations"
namespace: Application\Migrations
table_name: "app_auth.migration_versions"
name: Application Migrations
And I run the diff:
php app/console doctrine:migrations:diff
Unfortunately, the migration class generated is the following one:
namespace Application\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20160422171409 extends AbstractMigration
{
/**
* #param Schema $schema
*/
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
}
/**
* #param Schema $schema
*/
public function down(Schema $schema)
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SCHEMA app_auth');
}
}
what's wrong with my configuration then?
Dirty but working solution:
Tested with doctrine/migrations: 3.0.1
We can patch out the schema removing functionality of the DiffGenerator. I personally used this https://github.com/cweagans/composer-patches
Install the package, and then in composer.json "extra" section add:
"patches": {
"doctrine/migrations": {
"Change doctrine behavior to correctly pass PostgreSQL schema to schema_filter while diffing": "patches/doctrine-diff-generator.patch"
}
}
The patch file in patches/doctrine-diff-generator.patch:
--- lib/Doctrine/Migrations/Generator/DiffGenerator.php 2020-06-21 10:55:42.000000000 +0200
+++ lib/Doctrine/Migrations/Generator/DiffGenerator.patched.php 2020-12-23 12:33:02.689405221 +0100
## -142,8 +142,6 ##
*/
private function resolveTableName(string $name) : string
{
- $pos = strpos($name, '.');
-
- return $pos === false ? $name : substr($name, $pos + 1);
+ return $name;
}
}
Of course you have to bare in mind, that updates to doctrine could break the patch. And you are changing this functionality globally for your doctrine, so beware of breaking changes.
Personally, for my use case, which is adding doctrine entities into legacy database, without breaking it, this works nicely, and saves me from adding every new table managed by doctrine into the schema_filter.
Explanation:
When we look into DiffGenerator implementation it actually decodes the table names with schema correctly, but only when collecting the current database schema. This happens in PostgreSqlSchemaManager.php:
/**
* {#inheritdoc}
*/
protected function _getPortableTableDefinition($table)
{
$schemas = $this->getExistingSchemaSearchPaths();
$firstSchema = array_shift($schemas);
if ($table['schema_name'] === $firstSchema) {
return $table['table_name'];
}
return $table['schema_name'] . '.' . $table['table_name'];
}
But then then when calculating the target schema, this information is lost here in DiffGenerator.php:
/**
* Resolve a table name from its fully qualified name. The `$name` argument
* comes from Doctrine\DBAL\Schema\Table#getName which can sometimes return
* a namespaced name with the form `{namespace}.{tableName}`. This extracts
* the table name from that.
*/
private function resolveTableName(string $name) : string
{
$pos = strpos($name, '.');
return $pos === false ? $name : substr($name, $pos + 1);
}
And only afterwards the return value of this function is passed into the schema_filter. Unfortunate, but i guess there was a reason for this :)

Typo3 - Extbase CommandController for scheduler task

i ve created an empty extbase/fluid extension and added an ImportCommandController for a scheduler task. For some reason i am not able to load that task in my scheduler. Please note that i want to realise my task via CommandController (http://wiki.typo3.org/CommandController_In_Scheduler_Task) and NOT via \TYPO3\CMS\Scheduler\Task\AbstractTask.
ext_localconf.php
<?php
if (!defined('TYPO3_MODE')) {
die('Access denied.');
}
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'][] = 'VENDORx\\Sched\\Command\\ImportCommandController';
Classes/Command/ImportCommandController.php
<?php
namespace VENDORx\Sched\Command;
/**
*
*
* #package Sched
* #license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
*
*/
class ImportCommandController extends \TYPO3\CMS\Extbase\Mvc\Controller\CommandController {
public function importCommand($commandIdentifier= NULL) {
echo 'command run';
}
}
?>
any idea whats missing??
As Jost already mentioned you neet proper Annotations:
/**
* #param integer $commandIdentifier
*/
public function importCommand($commandIdentifier = NULL) {
$this->outputLine('command run');
}
Select "Extbase-CommandController-Task" in dropdown
You'll get another select field on the bottom where you can find your "ImportCommand" select and save

Magento 1.9 Wrong customer created and last login dates

I am running Magento v.1.9.0.1 and I am facing a problem with the dates displayed when editing a customer via the admin area. For example,
Last Logged In: 11 Feb 7791 4:23:48 μ.μ.
Last Logged In (Europe/Istanbul): 09 Feb 2015 3:16:31 μ.μ.
Account Created on: 02 Sep 2015 4:16:11 μ.μ.
The client registered on the 9th of February 2015. I searched around and found topics about other Magento versions that said for some dates Magento is swapping the dates, hence the difference between actual created date (09/02/2015) and reported created date (02/09/2015).
I couldn't find anything about version 1.9 nor anything about the year reported for last logged in (7791!).
Is there a fix for this problem?
Thank you for your time.
Faced same issue in Magento 1.8.1 , and applied below solution for account created date and last login date.Because some how Magento is converting day to month and month to date in customer edit section.
Path : app\code\core\Mage\Adminhtml\Block\Customer\Edit\Tab\View.php
Override below methods from above file :
public function getCreateDate()
{
$cutomerId = $this->getRequest()->getParam('id');
$connection = Mage::getSingleton('core/resource')->getConnection('core_read');
$select = $connection->select()
->from('customer_entity', array('created_at'))
->where('entity_id=?',$cutomerId);
$rowArray = $connection->fetchRow($select);
return $this->_getCoreHelper()->formatDate($rowArray['created_at'],
Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
}
public function getStoreCreateDate()
{
$cutomerId = $this->getRequest()->getParam('id');
$connection = Mage::getSingleton('core/resource')->getConnection('core_read');
$select = $connection->select()
->from('customer_entity', array('created_at'))
->where('entity_id=?',$cutomerId);
$rowArray = $connection->fetchRow($select);
return $this->_getCoreHelper()->formatDate($rowArray['created_at'],
Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
}
public function getLastLoginDate()
{
if ($date = $this->getCustomerLog()->getLoginAtTimestamp()) {
$date = Mage::app()->getLocale()->storeDate(
$this->getCustomer()->getStoreId(),
$date,
true
);
return $this->formatDate($date, Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
}
return Mage::helper('customer')->__('Never');
}
I have also faced the same issue for quite a long time till i found the solution http://www.customerparadigm.com/magento-bug-magento-customer-create-date-juxtaposition/
Summary of the files in the Magento Extension for solving the Magento Date Switch Fix:
Created.php:
app/code/local/CustomerParadigm/Datefix/Model/Entity/Attribute/Backend/Time/Created.php
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magento.com so we can send you a copy immediately.
*
// * DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magento.com for more information.
*
* #category Mage
* #package Mage_Eav
* #copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Entity/Attribute/Model - attribute backend default
*
* #category Mage
* #package Mage_Eav
* #author Magento Core Team <core#magentocommerce.com>
*/
class CustomerParadigm_Datefix_Model_Entity_Attribute_Backend_Time_Created extends Mage_Eav_Model_Entity_Attribute_Backend_Time_Created
{
/**
* Returns date format if it matches a certain mask.
* #param $date
* #return null|string
*/
/* This shouldn't be needed for the datetime switch bug fix. Removing for testing.
protected function _getFormat($date)
{
if (is_string($date) && preg_match('#^\d{4,4}-\d{2,2}-\d{2,2} \d{2,2}:\d{2,2}:\d{2,2}$#', $date)) {
return 'yyyy-MM-dd HH:mm:ss';
}
return null;
}
*/
/**
* Set created date
* Set created date in UTC time zone
*
* #param Mage_Core_Model_Object $object
* #return Mage_Eav_Model_Entity_Attribute_Backend_Time_Created
*/
public function beforeSave($object)
{
$attributeCode = $this->getAttribute()->getAttributeCode();
$date = $object->getData($attributeCode);
if (is_null($date)) {
if ($object->isObjectNew()) {
$object->setData($attributeCode, Varien_Date::now());
}
} else {
// Date switch fix
$date = strtotime($date);
// convert to UTC
$zendDate = Mage::app()->getLocale()->utcDate(null, $date, true);
$object->setData($attributeCode, $zendDate->getIso());
}
return $this;
}
/**
* Convert create date from UTC to current store time zone
*
* #param Varien_Object $object
* #return Mage_Eav_Model_Entity_Attribute_Backend_Time_Created
*/
public function afterLoad($object)
{
$attributeCode = $this->getAttribute()->getAttributeCode();
$date = $object->getData($attributeCode);
// Date switch fix
if (!is_null($date)) {
$date = strtotime($date);
}
$zendDate = Mage::app()->getLocale()->storeDate(null, $date, true);
$object->setData($attributeCode, $zendDate->getIso());
parent::afterLoad($object);
return $this;
}
}
app/code/local/CustomerParadigm/Datefix/etc/config.xml
<config>
<global>
<models>
<eav>
<rewrite>
<entity_attribute_backend_time_created>CustomerParadigm_Datefix_Model_Entity_Attribute_Backend_Time_Created</entity_attribute_backend_time_created>
</rewrite>
</eav>
</models>
</global>
</config>
/app/etc/module/ CustomerParadigm_Datefix.xml
<?xml version=”1.0″?>
<config>
<modules>
<CustomerParadigm_Datefix>
<active>true</active>
<codePool>local</codePool>
</CustomerParadigm_Datefix>
</modules>
</config>
I am not having much reputation to comment, so pointing out through a response:
#Digisha: You have mentioned this for getLastLoginDate()
public function getLastLoginDate()
{
if ($date = $this->getCustomerLog()->getLoginAtTimestamp()) {
$date = Mage::app()->getLocale()->storeDate(
$this->getCustomer()->getStoreId(),
$date,
true
);
return $this->formatDate($date, Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
}
return Mage::helper('customer')->__('Never');
}
I just want to ask if this is correct parameter for if condition:
if ($date = $this->getCustomerLog()->getLoginAtTimestamp())
I don't think so, you are assinging and then how is this correct??