TYPO3 new record appearing on wrong location in Backend List - typo3

I'm developing a new extension using ExtBase in TYPO3 (4.7) for a client.
I have however the strangest problem. In the back-end, my possible, new record types are - as usual - listed in the Insert new record Backend List. Usually each of these record-types are preceded by the module name (actually they are grouped right after the module name).. However, in my case, 1 or 2 of the record-types of any other extension appear within my extension's list as well.. I've been trying to figure out pretty much all that I can, I even copied the extension over to an entirely different TYPO3 installation, but the same problem persists..
If of any extension some records appear just below my extension's title, and I delete that particular extension, just some other record-types appear of another extension.
What's going on here??

Short & late answer:
i guess you have defined the title of your models in two different ways or with a non-existent languagefile in your ext_tables.php. Something like this:
Model1:
$TCA['tx_aaext_domain_model_one'] = array(
'ctrl' => array(
'title' => 'LLL:EXT:bn_news/Resources/Private/Language/locallang_db.xml:tx_bnnews_domain_model_categories',
Model2:
$TCA['tx_aaext_domain_model_two'] = array(
'ctrl' => array(
'title' => 'Static Title',
and/or your extension-name has an underscore like aa_extension, then this error can happen.
Make sure that both title-definitions are dynamic and begin with "LLL:EXT:" and point to an existing translation. Everything should be fine now.
Long answer will be to long :)

Related

TYPO3 - TCA Migrations - Informational or ToDo?

I'm a newbie in typo3. A friend of me asked, if I can upgrade his installation for him, because I'm a developer. So I checked if I can do it.
I did several steps to upgrade the installation from 7.6.9 to 8.7.3. Now I ended in the installation tool in the section important actions. There is a point TCA migrations.
There it says:
TCA migrations need to be applied Check the following list and apply
needed changes.
The icon path of wizard "link" from TCA table
"tx_myredirects_domain_model_redirect['columns']['destination']['config']['wizards']['link']['icon']"has
been migrated to
tx_myredirects_domain_model_redirect['columns']['destination']['config']['wizards']['link']['icon']"
= 'actions-wizard-link'. ...
Is this just informational or do I have to modify something in the things listed?
Sorry again, if this is a newbie question, but I am actually a newbie in typo3.
If the extensions that need to migrate the TCAs haven't been created by you, then no, you do not really need to change them. The author of the extension should do it, because if you change them and then the author releases an update, then all your changes will be lost.
If the extension is a custom extension, then it would be better to migrate them. Then you can avoid bugs and unwanted disfunctions.
If you have a sitepackage, you can override the TCA's and give them new definitions. This way, if the author releases an update, your TCAs won't be lost. In order to do that, you can follow these instructions:
Extending TCAs
An example would be:
your_sitepackage/Configuration/TCA/Overrides/tx_tablename_domain_model_modelname
$GLOBALS['TCA']['tx_tablename_domain_model_modelname']['columns']['columnYouNeedToChange'] = [
'label' => 'input_29 link',
'config' => [
'type' => 'input',
'wizards' => [
'link' => [
'type' => 'popup',
'title' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_link_formlabel',
'icon' => 'actions-wizard-link',
'module' => [
'name' => 'wizard_link',
],
'JSopenParams' => 'height=800,width=600,status=0,menubar=0,scrollbars=1',
'params' => [
'blindLinkOptions' => 'folder',
'blindLinkFields' => 'class, target',
'allowedExtensions' => 'jpg',
],
],
],
]
This for example would solve the first problem of the image you shared. You just need to replace the table name. (That's TYPO3v8. TYPO3 v9 has more changes when it comes to TCAs)
If you are not sure how the path to the column look like ($GLOBALS['TCA']['tx_tablename_domain_model_modelname']['columns']['columnYouNeedToChange']) then follow this:
TCA Paths
#Thomas Löffler is right. It would be very useful to create an issue on GitHub and let the author know that some changes need to be made.
Best regards
This will show which TCA fields have been identified to have a legacy format and have been transformed while loading the configuration files.
While it is good practice to do these changes and keep this clean, strictly speaking it is not required.
Tip: I would rather look there before an upgrade because deprecated stuff might still have an upgrade path in an older version but none in the newest.

How to manage different versions of application by using plugins in cakephp 3?

I have a single cakephp 3 application
I have a generic view which render data depending of an array struture of fields configured in each Model, this array includes configurations for display each field in the view like (text titles, maxsize, sortable, etc..) and database configuration like (column name in the database/table, datatype, etc..) in the same array, and its working fine.
public $tableData = [
[
'name' => 'Table1.name',
'title' => 'Name',
'field' => 'name',
'sortable' => true,
'type' => 'string',
'size' => '50px',
],
[
'name' => 'Asosiation1.option',
'title' => 'Topic',
'field' => 'topic_option',
'sortable' => true,
'type' => 'string',
'size' => '150px',
],
... More fields and asosiations
]
But now, i need to have these same Models in different versions, because the structure of the database/table for each Model change every year, but i need to preserv/show the data corresponding to each version as it is.
So if a user request mySite.com/2010, Site must show data using Model array structure defined for that year especifically.
So, i created:
/plugins/Years/version2010
/plugins/Years/version2011
etc..
and in each pluging, I copied all Models changing only the namespace, defaultConnectionName (1 schema per Year) and array structure.
This provokes to have mutiple plugins loaded in bootstrap config.
Is there any way to load only the necesary plugin depending of the request ?(/2010, /2011, etc..)
Ex. In bootstrap.php I do for each plugin year:
Plugin::load('Years/version201X', ['bootstrap' => false, 'routes' => true]);
also
Is there any way to avoid having to specify the plugin name every time i do loadModel() or TableRegistry::get() ?
Ex. In main App GeneralController I have to do every time:
$this->loadModel('Years/version201X/Table1');
Or maybe there is another better approach to solve this situation i havent seen
Is there any way to load only the necesary plugin depending of the
request ?(/2010, /2011, etc.
Yes. Inside config/bootstrap.php you can check the request uri and then have a switch statement for the plugins. Something like this:
$uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_SPECIAL_CHARS);
// might need explode('/', $uri); to extract the right URL component
switch ($uri) {
case '2011':
// load plugin
break;
case '2012':
// log plugin
break;
}
You probably dont even need the switch statement, be creative there. Obviously thats not exact, but if gives you the right idea.
Is there any way to avoid having to specify the plugin name every time
i do loadModel() or TableRegistry::get() ?
If the model is unique to the plugin then I am not sure how you get away with this. Whats the problem though? Just a few extra characters. Sounds like you only have to do this once per year, right? However, you might not have to specify that if you're within the scope of the plugin. I am not sure on that, but its worth trying.

How can I access custom validators globally?

I created a my own validation class under /library/My/Validate/
In my form I have $this->addElementPrefixPath('My_Validate', 'My/Validate', 'validate');
I am using my validator like so:
$this->addElement('text', 'aField', array(
'validators' => array(
array('TestValidator', false, array('messages' => 'test failed')
),
));
This all works. However, I am interested in improving this in two ways.
I would like to make it so that all forms have access to my validator. Calling addElementPrefixPath() in every form doesn't seem to be a clean way of doing this.
I would like to pass in My_Validate_TestValidator instead of TestValidator so other developers know what they are working with right away.
To answer your first question, the only real easy way to do this would be to create your own instance of the form - My_Form_Abstract - which has an init() method that sets the prefix path - and then of course calls the parent init().
I'm not aware of a way to make your second method work flawlessly. You need to store a prefix in order to build the validator loader correctly. However, as an alternative, you might try creating new instances of the class using the full name, and then adding it to the element:
$element = $this->getElement('aField');
$myValidateTestValidator = new My_Validate_TestValidator();
$element->addValidator($myValidateTestValidator);

Programmatically adding an article to Joomla

I am very new to Joomla (frankly just started exploring the possibility of using Joomla) and need help with programmatically adding articles to Joomla backend tables (please see details below). Also along the same lines, I would like to understand how should values for the columns:
parent_id
lft
rgt
level
be generated for the table jos_assets (#__assets) and what is their functional role (eg are they “pointers/indexes” analogous to, say, an os inode to uniquely indentify a file or are they more functional attributes such as identifying the category, subcategory etc)
It might help to use the following SIMPLIFIED example to illustrate what I am trying to do. Say we have a program that collects various key information such as names of the authors of web articles, the subject type of the articles, the date of articles as well as a link to the article. I want to be able to extend this program to programmatically store this information in Joomla. Currently this information is stored in a custom table and the user, through a custom php web page, can use search criteria say by author name, over a certain range of dates to find the article(s) of interest. The result of this search is then displayed along with a hyperlink to the actual article. The articles are stored locally on the web server and are not external links. The portion of the hyperlink stored in the custom table includes the relative path of the physical document (relative to the web root), so for example:
Author date type html_file
Tom 08-14-2011 WEB /tech/11200/ar_324.html
Jim 05-20-2010 IND /tech/42350/ar_985.html
etc.
With all the advantages that Joomla offers over writing custom php search and presentation pages as well as trending etc, we would really like to switch to it. It seems that among other tables for example that #__assets and #__content can be populated programmatically to populate Joomla from our existing php program (which is used to compile the data) and then use Joomla.
Any examples, suggestions and help is greatly appreciated
Kindest regards
Gar
Just an initial note: Joomla 1.6/1.7 are pretty similar. 1.5 not so much. I'll assume 1.6/1.7, as that's what I'd recommend as a base for a new project.
First up, you'll need to be running with access to the Joomla framework. You could do this through a Component, or a module, or a cron that bootstraps it or whatever. I won't go though how to do that.
But once you do that, creating an article is reasonably simple.
<?php
require_once JPATH_ADMINISTRATOR . '/components/com_content/models/article.php';
$new_article = new ContentModelArticle();
$data = array(
'catid' => CATEGORY_ID,
'title' => 'SOME TITLE',
'introtext' => 'SOME TEXT',
'fulltext' => 'SOME TEXT',
'state' => 1,
);
$new_article->save($data);
The actual list of fields will be a bit longer than that (required fields etc), but you should get sane error messages etc from the Joomla framework which illuminate that.
So in summary:
Load up the Joomla framework so you have access to the DB, components, models, etc
Include the com_content article class, which will handle validation, saving to the database etc for you
Create an article instance with the required fields filled in as appropriate
Call save()
Now that I think about it, that'll probably work in 1.5...
Found a better way to do this without any errors Create a Joomla! Article Programatically
$table = JTable::getInstance('Content', 'JTable', array());
$data = array(
'catid' => 1,
'title' => 'SOME TITLE',
'introtext' => 'SOME TEXT',
'fulltext' => 'SOME TEXT',
'state' => 1,
);
// Bind data
if (!$table->bind($data))
{
$this->setError($table->getError());
return false;
}
// Check the data.
if (!$table->check())
{
$this->setError($table->getError());
return false;
}
// Store the data.
if (!$table->store())
{
$this->setError($table->getError());
return false;
}

Correct routing for a Rest API with Zend

I'm trying to implement a REST API to my website.
My problem is that the default Zend routing gets in the way. I've first tried using Zend_Rest_Route but I haven't been able to understand how I was supposed to use it correctly for "deep" routes, aka website/api/resource1/filter/resource2/id.
Using the default Zend routing, I'd need to create a gigantic Resource1Controller to take care of all the possible actions, and I don't think it's the "good" way to do this.
I've tried using Resauce ( http://github.com/mikekelly/Resauce/), creating an api module and adding routes, but I'm not able to get it working correctly :
The patterns I added were :
$this->addResauceRoutes(array(
'api/resource' => 'resource',
'api/resource/:id' => 'custom',
'api/resource/filter' => 'resource-filter',
'api/resource/filter/:id' => 'custom',
));
Which then leads to this :
public function addResauceRoutes($routes) {
$router = Zend_Controller_Front::getInstance()->getRouter();
foreach ($routes as $pattern => $controller) {
$router->addRoute($controller,
new Zend_Controller_Router_Route($pattern, array(
'module' => 'api',
'controller' => $controller
)
)
);
}
Zend_Controller_Front::getInstance()->setRouter($router);
website/api/resource gets me the
Resource1Controller, ok
website/api/resource/filter gets me to the
resource1filterController, ok
website/api/resource/filter/:id gets me to
a custom controller, ok
I'd like for website/api/resource/:id to get me to the same custom controller... But it redirects me to the Resource1Controller.
What solution is there for me to correctly create my API ? Is there a good way to do this with Zend_Rest_Route ?
Edit : Mike,
I felt that it was not appropriate for me to use different controllers since I need the pathes "website/api/resource/:id" and "website/api/resource/filter/:id" to give me almost the exact same result (the only difference is that because the filter is there, I may get a message telling "content filtered" here).
I thought it was a waste creating another almost identical controller when I could've used the same controller and just checked if a parameter "filter" was present.
However, I don't want to use the basic Zend routing since for the path "website/api/resource/filter/resource2" I'd like to have a totally different comportment, so I'd like to use another controller, especially since I'm trying to use Zend_Rest_Action and need my controllers to use the basic actions getAction(), putAction(), postAction() and deleteAction().
Please could you explain why it is you need two URI patterns pointing to the same controller. A better solution might be to use a separate controller for each of the two patterns and move any shared logic into your model.
Forcing a unique controller for each routing pattern was an intentional design decision, so I'd be interested to hear more detail about your use case where you feel this isn't appropriate.
I thought it was a waste creating
another almost identical controller
when I could've used the same
controller and just checked if a
parameter "filter" was present.
Personally, I think it is cleaner to move the shared logic into the model and to keep your controllers skinny. To me it's not wasteful, it's just more organised - it will make your code easier to manage over time.
If you really need to use the same controller you could always use a query parameter instead, that would work fine:
api/resource/foo?filter=true
That URI would be taken care of by the first route ('api/resource/:id' => 'custom') for free.
But please consider using two controllers, I think that is a better approach.
Okay, the reason I didn't get the good controllers was because Resauce uses the controller name as the name of the route, which has to be unique - so second url pointing to "custom" controller couldn't work. Now I'm able to get the files I want :)
So instead of what was previously noted, I use directly the $router->addRoute(); and define new names each times, even if pointing to the same controller.
Example :
$router->addRoute('resource', new Zend_Controller_Router_Route('/api/resources/:id', array('module' => 'api', 'controller' => 'resource')));
$router->addRoute('resourceFiltered', new Zend_Controller_Router_Route('/api/resources/filter1/:id', array('module' => 'api', 'controller' => 'resource', 'filter' => 'filter1'));