Wrong title for every module on website - magento2

Magento 2 show wrong title for every module on website, example module warranty and payment (Create new customer account). It show for title path vendor/magento/module-theme/view/frontend/templates/html/title.phtml
How i can solve this problem?

Fixed setting the title in my custom modules, at \Vendor\Module\Controller\Index, per example.
/**
* #var \Magento\Framework\View\Result\PageFactory
*/
protected $_resultPageFactory;
/**
* #param Context $context,
* #param \Magento\Framework\View\Result\PageFactory $resultPageFactory,
*/
public function __construct(Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory)
{
$this->_resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* return page factory
*/
public function execute()
{
$resultPage = $this->_resultPageFactory->create();
$resultPage->getConfig()->getTitle()->set(__('My Module Title'));
return $resultPage;
}

Check that you don't have an extension adding a block into the customer area that extends from the Magento\Sales\Block\Order\History block. This block sets the page title in the constructor. I have seen an extension that did this and several account sections then had the page title of "My Orders".

Related

Dynamic recipient in form

I have a custom extension with list and detail of teachers. On the detail page I include a form with code:
<formvh:render persistenceIdentifier="1:/form_definitions/myform.yaml" />
I need to set the recipient with the teacher's email shown on the page. How can I do?
You can achieve that by writing a custom form finisher.
Add a hidden field to your form which holds the the ID of the teacher
Fetch that id in your form finisher and load the Teacher model by your repository
A (not complete) example of a form finisher, which loads recipient data from a custom model and sends the mail to this specific data:
class EmailToContactPersonFinisher extends EmailFinisher
{
/**
* Executes this finisher
* #see AbstractFinisher::execute()
*
* #throws FinisherException
*/
protected function executeInternal()
{
/** #var FormRuntime $formRuntime */
$formRuntime = $this->finisherContext->getFormRuntime();
if ($formRuntime->getResponse()->getRequest()) {
if ($formRuntime->getResponse()->getRequest()->hasArgument('contactPerson')) {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** #var ContactPersonRepository $repository */
$contactPersonRepository = $objectManager->get(ContactPersonRepository::class);
/** #var ContactPerson $contactPerson */
$contactPerson = $contactPersonRepository->findByUid($formRuntime->getResponse()->getRequest()->getArgument('contactPerson'));
}
}
// override contactPerson related options
if ($contactPerson instanceof ContactPerson) {
if ($contactPerson->getEmail()) {
$recipientAddress = $contactPerson->getEmail();
}
}
$this->setOption('recipientAddress', $recipientAddress);
parent::executeInternal();
}
}
You can also have a look at the standard emailFinisher, which gives you quick idea on the architecture.
sysext/form/Classes/Domain/Finishers/EmailFinisher.php

TYPO3 & tx_news need ViewHelper for show count of Entities in category

Task: in category menu show count of item in each category, like
Category_one (38)
Category_two (14)
Etc ...
I have try count by $demand but did'nt work
<?php
namespace HIT\huskytheme\ViewHelpers\News;
class CountCategoriesViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* #var \GeorgRinger\News\Domain\Repository\NewsRepository
* #inject
*/
protected $newsRepository = null;
/**
*
* #param string $category
* #return string
*/
public function render($category) {
$demand = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('GeorgRinger\\News\\Domain\\Model\\Dto\\NewsDemand');
//$demand->setDateField('datetime');
$demand->setStoragePage(10, true);
// for example by id = 2
$demand->setCategories(2);
$demand->setCategoryConjunction('and');
$demand->setIncludeSubCategories('1');
//$demand->setArchiveRestriction($settings['archiveRestriction']);
$statistics = $this->newsRepository->countByCategories($demand);
\TYPO3\CMS\Core\Utility\DebugUtility::debug($statistics);
return $this->newsRepository->countByCategories($demand);
}
}
But get just 0, if call
{namespace s=HIT\huskytheme\ViewHelpers}
{s:news.countCategories(category: 2)}
Actualy i found way to get number of news in Category. Thx Georg Ringer and undko
My ViewHelper
<?php
namespace HIT\huskytheme\ViewHelpers\News;
class CountCategoriesViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* #var \GeorgRinger\News\Domain\Repository\NewsRepository
* #inject
*/
protected $newsRepository = null;
/**
*
* #param \GeorgRinger\News\Domain\Model\Category $category
* #return string
*/
public function render($category) {
/* #var $demand \GeorgRinger\News\Domain\Model\Dto\NewsDemand */
$demand = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\GeorgRinger\News\Domain\Model\Dto\NewsDemand::class);
$demand->setCategories(array($category));
$demand->setCategoryConjunction('and');
$demand->setIncludeSubCategories(false);
return count($this->newsRepository->findDemanded($demand));
}
}
And in my tx_news Templates/Category/List.html
<!-- load my ViewHelper -->
{namespace s=HIT\huskytheme\ViewHelpers}
and here add count
...
<f:link.page title="{category.item.title}" class="current-item" pageUid="{settings.listPid}"
additionalParams="{tx_news_pi1:{overwriteDemand:{categories: category.item.uid}}}">{category.item.title}
<span class="postnum">({s:news.countCategories(category: category.item)})</span>
</f:link.page>
...
There is no method countByCategories which implements something like a demand object. Please just use a direct call to the DB.
Depending on the number of categories and the need to show this menu on uncached pages I‘d suggest to not go the view helper way but query DB (as Georg suggested) directly in the controller. Just connect a slot of yours to signal GeorgRinger\News\Controller\CategoryController : listAction. You‘ll get all categories there (in argument categories) and can launch a
SELECT COUNT(*) FROM sys_category_record_mm … GROUP BY uid_local
to fetch all counts in one go. Then simply add a new key to the array you return and use it in your template under that name.

Call to undefined method getPosition() - Why and Fix

I made an extbase extension with a class Appointment with a property expertises und another one subExpertises of the same type.
This is how they look like in the Appointment class (subExpertises is the same):
/**
* expertises
*
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<...\Domain\Model\Expertise>
*/
protected $expertises = NULL;
/**
* Adds an expertise
*
* #param ...\Domain\Model\Expertise $expertise
* #return void
*/
public function addExpertise(...\Domain\Model\Expertise $expertise) {
$this->expertises->attach($expertise);
}
I get an error when executing this code in my controller after editing the appointment in a fluid form:
/**
*
* #param \Domain\Model\Appointment $appointment
* #return void
*/
public function bookAction(\Domain\Model\Appointment $appointment) {
//empty all expertises of appointment - then fill them with the selected from lawyer
$appointment->setExpertises(new \TYPO3\CMS\Extbase\Persistence\ObjectStorage());
$appointment->setSubExpertises(new \TYPO3\CMS\Extbase\Persistence\ObjectStorage());
//add all checked expertises of lawyer to appointment
foreach ($appointment->getLawyer()->getExpertises() as $expertise) {
if ($expertise->getChecked()) {
$appointment->addExpertise($expertise);
}
foreach ($expertise->getSubExpertises() as $subExpertise) {
if ($subExpertise->getChecked()) {
$appointment->addSubExpertise($subExpertise);
}
}
}
$this->appointmentRepository->update($appointment);
}
This is the error:
Fatal error: Call to undefined method \Domain\Model\Expertise::getPosition() in /var/www/typo3_src/typo3_src-6.2.25/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php on line 453
Now it seems that TYPO3 thinks Expertise is of type ObjectStorage because it tries to call getPosition() but I have no clue why it does that and what I should change in order to successfully save my Appointment object with the new Expertises.
I tried debugging the appointment object, but I couldn't find the problem - it seems okay to me, it just shows that expertises und subExpertises have been modified.
Getter methods in Extbase aren't magic, you have to explicitly define them.
If you're dealing with a n:n-relation, you also need to initialize the Property as ObjectStorage in your model and configure it in the TCA.
/**
* Initialize all ObjectStorage properties.
*
* #return void
*/
protected function initStorageObjects() {
$this->yourProperty = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}

__toString() must return a string value when submitting a form

I have an show view that I had to custom a little bit so we can edit things in it. Among these things there is a multi select that is the result of a query to filter schools I've done inside the controller, sent via the render method.
Before all that, I was using a many-to-many multi select form to select every schools ever saved in the database. Now I want to use it so I can use what's already working.
Since it's sent via the render and not the form, I managed to create an HTML form, to display it, and to get to see what has been selected when I submit the form, however I had several problems:
First of all, it wanted to be an instance of an object, and to be able to save an object instead of an array. I managed to do that by doing the following:
$object = new Ecole();
foreach ($ecolesDispo as $key => $value)
{
$object->$key = $value;
}
$mission->addEcolesDispo($object);
(Ecole is for schools)
The problem I'm now stuck with came right after it, because now it wants it to be converted to string, however, I can't manage to do so.
Here's how the concerned part of my entity looks like.
/**
* Constructor
*/
public function __construct()
{
$this->ecolesDispo = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #return string
*/
public function __toString()
{
return (string) $this->addEcolesDispo($object);
//Not sure about that part though
}
/**
* Add ecolesDispo
*
* #param \EcoleBundle\Entity\Ecole $ecolesDispo
*
* #return Mission
*/
public function addEcolesDispo(\EcoleBundle\Entity\Ecole $ecolesDispo)
{
$this->ecolesDispo[] = $ecolesDispo;
return $this;
}
/**
* Remove ecolesDispo
*
* #param \EcoleBundle\Entity\Ecole $ecolesDispo
*/
public function removeEcolesDispo(\EcoleBundle\Entity\Ecole $ecolesDispo)
{
$this->ecolesDispo->removeElement($ecolesDispo);
}
/**
* Get ecolesDispo
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEcolesDispo()
{
return $this->ecolesDispo;
}
How can I convert this to string?
Thank you in advance
Your __toString function should looks like :
public function __toString()
{
return $this->id; // Because __toString seems to be called to set your $key variable...
}
-> rely on a string property.
In your __toString() function, you use (string) which will implicitely call ... __toString() to convert $this to a string. That would be a circular call.
Try this if there's a string variable name in the entity where you were using __toString or use any string type property of that entity which specifies the entity itself.
public function __toString()
{
// Or change the property that you want to show
return $this->name;
}

Extbase stores empty values in database

I am trying to create an object, but the values are not stored into the database. This is done on an "index"-action because the plugin is inserted via TypoScript and actually does not create output. So there is no object given when calling the action, that's why I am creating it by myself.
$stat = new Tx_MyExt_Domain_Model_Stat;
$stat->setSubscriberId($_COOKIE['statid']);
$stat->setDomain($_SERVER['HTTP_HOST']);
$stat->setRequestUri($_SERVER['REQUEST_URI']);
$this->statRepository = t3lib_div::makeInstance('Tx_myExt_Domain_Repository_StatRepository');
$this->statRepository->add($stat);
doing a var_dump($stat) gives the following:
object(Tx_MyExt_Domain_Model_Stat)#191 (9) {
["subscriber_id":protected]=>
string(1) "2"
["domain":protected]=>
string(22) "test.localhost.example"
["request_uri":protected]=>
string(26) "/testpage/index.php?id=2"
["uid":protected]=>
NULL
["_localizedUid":protected]=>
NULL
["_languageUid":protected]=>
NULL
["pid":protected]=>
NULL
["_isClone":"Tx_Extbase_DomainObject_AbstractDomainObject":private]=>
bool(false)
["_cleanProperties":"Tx_Extbase_DomainObject_AbstractDomainObject":private]=>
NULL
}
So this looks like the values are assigned properly. But when looking into the database, I get this:
uid pid subscriber_id domain request_uri crdate
13 0 0 NULL NULL 1328176026
Repository:
class Tx_MyExt_Domain_Repository_StatRepository extends Tx_Extbase_Persistence_Repository
{}
Model:
class Tx_MyExt_Domain_Model_Stat extends Tx_Extbase_DomainObject_AbstractEntity
{
/**
* #var int
* #dontvalidate
*/
protected $subscriber_id = 0;
/**
* #var string
* #dontvalidate
*/
protected $domain = '';
/**
* #var string
* #dontvalidate
*/
protected $request_uri = '';
/**
* #param int $susbcriber_id Subscriber id
* #return void
*/
public function setSubscriberId($subscriber_id)
{
$this->subscriber_id = $subscriber_id;
}
/**
* #return int Susbcriber id
*/
public function getSubscriberId()
{
return $this->subscriber_id;
}
/**
* #param string $domain Domain
* #return void
*/
public function setDomain($domain)
{
$this->domain = $domain;
}
/**
* #return string Domain
*/
public function getDomain()
{
return $this->domain;
}
/**
* #param string $request_uri Request URI
* #return void
*/
public function setRequestUri($request_uri)
{
$this->request_uri = $request_uri;
}
/**
* #return string Request URI
*/
public function getRequestUri()
{
return $this->request_uri;
}
}
Can someone give me advise what may be wrong here?
Debugged through the whole extbase process. It seems that in typo3/sysext/extbase/Classes/Persistence/Backend.php, the attributes are skipped on this line:
if (!$dataMap->isPersistableProperty($propertyName) || $this->propertyValueIsLazyLoaded($propertyValue)) continue;
This because $dataMap->isPersistableProperty($propertyName) doesn't return something. Investigating in typo3/sysext/extbase/Classes/Persistence/Mapper, there is:
/**
* Returns TRUE if the property is persistable (configured in $TCA)
*
* #param string $propertyName The property name
* #return boolean TRUE if the property is persistable (configured in $TCA)
*/
public function isPersistableProperty($propertyName) {
return isset($this->columnMaps[$propertyName]);
}
So the solution is quite simple: create a valid TCA. I didn't had one (or a too minimalistic) since the table i am using is not going to be displayed in the backend.
While misconfiguration of TCA might be causing the problem, there might be others. For example, extbase does not like it when you are defining unique keys and fails silently.
Having struggeld with the problems in multiple projects, I am now using the following debugging routine for projects made with the extension builder
Remove your own additions from the table related classes and as well from typoscript. This has to be done for ext_tables.php, ext_tables.sql, all files in Configuration/TCA and Configuration/Typoscript if you have changed their state in Configuration/ExtensionBuilder/settings.yaml to merge or keep.
Check if your application now does save. If not, report a detailed bug report to exentension builder.
Normally your application should save now. Readd recursively the changes you've made until you find the error. Start with ext_tables.sql (don't forget you have to remove and readd the database every time), go on with ext_tables.php, Configuration/TCA/* and end with Configuration/Typoscript (it's my personal experience that these order is the fastest)
Report your stuff to the extbase team and add it to this thread (as it's the first google hit when you experience the error)