I have an extension with custom tables, one of those I can't get to work. When I try to findOneByUid() from it, I seem to get the right record but except from uid and pid all properties have a value of null.
The name of the table is: tx_myext_domain_model_advertisercategories. I used to have an underscore between advertiser and categories, but it seems this is the way extbase expects it.
I have configured:
ext_tables.php & ext_tables.sql
\Domain\Model\Advertisercategories.php
\Domain\Repository\AdvertisercategoriesRepository.php
\Configuration\TCA\Advertisercategories.php
I have uploaded these files to Github here:
https://gist.github.com/kuipersb/4a5ef7f14ecc979866ae
The output I get when executing findOneByUid() or my custom method searchAdvertiser() is the following:
object(VENDOR\MyExt\Domain\Model\Advertisercategories)[334]
protected 'advertiserId' => null
protected 'name' => null
protected 'uniqueCode' => null
protected 'discount' => null
protected 'uid' => int 1
protected '_localizedUid' => int 1
protected '_languageUid' => null
protected 'pid' => int 2
private '_isClone' (TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) => boolean false
private '_cleanProperties' (TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) =>
array (size=6)
'advertiserId' => null
'name' => null
'uniqueCode' => null
'discount' => null
'uid' => int 1
'pid' => int 2
But I would expect:
advertiserId: 2
name: Test
unique_code: test
discount: 10.00
Any help greatly appreciated!
Looks like you have "adjusted " some things in the code yourself. The data type \string should just be string I guess. The model \VENDOR\MyExt\Domain\Model\Advertisers should (by naming convention) be named in singular, so just \VENDOR\MyExt\Domain\Model\Advertiser and the member variable of your class should just be $advertiser instead of $advertiserId.
When you put in an object in the code, TYPO3 will only write the uid into the field, so no need to name fields with id in the end any more.
My problem was in the ext_tables.php. The part that says:
'dynamicConfigFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Configuration/TCA/Advertisers.php',
On the end it should not be Advertisers.php, but AdvertiserCategories.php. One little typo.. :)
Thanks for your taking the time to investigate though Michael! It's alot of code I attached.
But the plural vs. singular names seems to be no problem. Although it would be better to go with singular names next time, I agree on that with you :)
Related
Basically: Every time I add a new class/model with the extension_builder and then want to create a record of that class I get the following error message:
2: SQL error: 'Unknown column 'edited' in 'field list''
(tx_icingaconfgen_domain_model_checkperiod:NEW5a27f9da8a41d636846075)
The interesting thing is: "edited" is NOT a property of that class, but the property of other classes in that extension. I've searched through the TCA of the class that throws the error and also the MySql table itself, but the field "edited" is indeed not part of that class. What's going on here?
Edit: What I find interesting is the fact that when I add a column "edited" to MySql table manually, the record can be created. But in no way I'm using this property in my Model. Why does it require a MySql column of that name then?
Without seeing the code I can only guess whats going on. Surely the field is requiered when a record is persisted. So it is possible that you referenced it in your TCA. If not in the columns maybe in the ctrl section:
'ctrl' => [
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
...
],
These fields are updated automatically if a recods is changed or created. There are more of those fields. So check your ctrl section.
It is also possible that you map another property (possibly even of another class) to that database field in your TypoScript like this:
plugin.tx_myextension {
persistence {
classes {
MyVendor\MyExtension\Domain\Model\Person {
mapping {
tableName = tt_address
recordType = \MyVendor\MyExtension\Domain\Model\Person
columns {
birthday.mapOnProperty = dateOfBirth
}
}
}
}
}
}
Example taken from here.
As it turned out the culprit was actually this line of code in the ext_localconf.php:
$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['extkey'] = 'Cjk\\Icingaconfgen\\Hook\\EvalHook';
$GLOBALS ['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['extkey'] = 'Cjk\\Icingaconfgen\\Hook\\EvalHook';
It's a hook that I've implemented into my extension that just marks if a record has been edited in the BE or not. I actually use this Hook that whenever a record is edited changes the propety edited from 0 to 1. This is intended of course, but the class checkperiod doesn't have the property 'edited'. But since the hook for the Datamapper works with every record that is changed or created it also tries to change 'edited' in classes that don't have this property. A simple if condition in the Hook itself, if the key 'edited' of the $fieldArray is NULL solved my problem.
class EvalHook {
function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray, &$pObj) {
if($status == "update" && $table != 'tx_icingaconfgen_domain_model_checkperiod'){
$fieldArray[edited] = 1;
}
elseif($status != "update" && $table != 'tx_icingaconfgen_domain_model_checkperiod){
$fieldArray[edited] = 0;
}
}
}
I'm not quite sure about the way of doing.
The challenge:
I call an addAction which shows a form. The point of calling the addAction gives two routing parameters, say value1 and value 2 separated by an "-".
I need value 1 and value 2 to search a pk in a table which will be saved as a foreignkey value by the addAction. I take both values give it to a method and get the key I need, that is tested and ok so far.
My problem.
In the first call of addAction I get the routing parameters and find the key. But afterwards of course it is forgotten. How can I remember the found value, so that I can use it for my saveModel method?
What would be the best way?
Idea 1:
Can I give it to the form and set it as value to the hidden keyfield?
For example:
class PadForm extends Form
{
public function __construct($name = null, $unitpartid)
{
parent::__construct('pad');
$this->add([
'name' => 'UnitPartPadID',
'type' => 'hidden',
'value' => $unitpartid,
]);
Would this be working? And would this be an accepted, proper way?
Idea 2:
Or would I try to use an instance variable in my controllerclass, like $this->smtg; ?
In both cases I get an understandable error
Trying to get property of non-object
Questions:
what would be the best way?
and
how to do it, perhaps somebody could give a short example.
EDIT:
I really would appreciate to learn about the best way. I now tried to give a variable to my form and then fill in some field, but that doesn't work.
Part of Controlleraction
(the action works if I set a constant value for the related field)
$parameter = $this->params()->fromRoute('id');
// echo $parameter;
$partnumber =substr($parameter,0,strpos($parameter,"-"));
// echo $partnumber;
$unitid=substr($parameter, strpos($parameter,"-")+1, strlen($parameter));
// echo $unitid;
$test=$this->unitparttable->getUnitPartID($unitid, $partnumber);
echo $test->UnitPartID;
$form = new PadForm(NULL, $test->UnitPartID);
Then in the Formclass:
public function __construct($name = null, $unitpartid)
{
// We will ignore the name provided to the constructor
parent::__construct('pad');
// $this->db=$db;
$this->add([
'name' => 'UnitPartPadID',
'type' => 'hidden', //hidden
]);
$this->add([
'name' => 'UnitPartID',
'type' => 'text', //hidden
'value' => $unitpartid,
]);
The question is now, how to fill the formfield UnitPartID with the value of $unitpartid given within the constructor.
I also tried $form->populate but it is unknown, I used it in ZEND1 before, but probably it doesn't exist anymore.
any help appreciated!
I know about the relationship but they only get the primary field, not the other fields. For example, I have two modules, module 1 holds the personal information of the user while module 2 let us say holds the person's activities. in module 2 I would like to display the gender base on his information from module 1.
How can I proceed with this?
Please follow below steps to achieve this:
Note: Make sure the Module-1 and Module-2 has one of the relationship 1-M or M-M
Step-1: Create new field in Module-2 to store/display the gender
values
Step-2: Create new file in Module-2
location(custom/modules/Module2/views/view.detail.php)
<?php
require_once('include/MVC/View/views/view.detail.php');
class Module2ViewDetail extends ViewDetail {
function Module2ViewDetail() {
parent::ViewDetail();
}
function display() {
$recordId = $this->bean->id;
global $db;
if($recordId){
/* write a query to fetch gender($gender) from module */
}
$this->dv->process();
$this->ss->assign('GENDER',$gender);
echo $this->dv->display();
}
}
?>
Step 3: \custom\modules\Module2\metadata\detailviewdefs.php
Add the customCode in the gender field which you have created in Module2 like below. (Please note: Give the name of field similar to you custom field name):
1 =>
array (
0 =>
array (
'name' => 'gender_c',
'label' => 'LBL_GENDER',
'customCode' => '{$GENDER}',
),
1 => '',
),
Hope this will help you. Thanks!
I had an Include method like so
public static IQueryable<SlideSet> IncludeParameters(this IDbSet<SlideSet> storage) {
return storage.Include(ss => ss.Params.Select(x => x.Parameter));
}
I am cleaning up my domain model and it no longer makes sense to have SlideSet.Params be public.
I know that there is a form of IDbSet<>.Include() that takes a string parameter. What is the syntax for using a string while descending into the child property like this?
btw, for those who are wondering, I'm pretty sure
return storage.Include(ss => ss.Params.Select(x => x.Parameter));
is identical to
return storage.Include(ss => ss.Params.Include(x => x.Parameter));
Just use .:
return storage.Include("Params.Parameter");
I ran into a problem what i cant really solve (i am a begginer with fuelphp).
So when i place input in my model i get this error
ErrorException [ Error ]: Class 'Model\Input' not found
when i try with session its the same thing
ErrorException [ Error ]: Class 'Model\Session' not found
And when i try to hardcode a value in it its not inserting, debuged the query no errors. it shows the value is posted (when passing hard code value) but not inserts it in the database.
my code
model
namespace Model;
use DB;
class Event extends \Model {
static function send_event()
{
$query = DB::insert('events');
$query->set(array(
'user_id' => Session::get('sentry_user'),
'event_name' => Input::post('event_name'),
'event_desc' => Input::post('event_desc'),
'event_start' => Input::post('event_start'),
'event_end' => Input::post('event_end'),
));
}
}
controller
function action_send_data()
{
$response = Response::forge();
$val = Validation::forge('events');
$val->add_field('event_name', 'Esemény neve', 'required');
$val->add_field('event_desc', 'Esemény leírás', 'required');
$val->add_field('event_start', 'Esemény kezdődik', 'required');
$val->add_field('event_end', 'Esemény kejár', 'required');
Event::send_event();
$response->body(json_encode(array(
'status' => 'ok',
)));
return $response;
}
could please someone give me a hint what i am doing wrong?
thank you
P.S: in the controller i removed the validation for query debuging
When you declare a namespace at the top of a file as you have done with
namespace Model;
This declares the namespace for all classes called where the namespace is not explicitly defined. For example, your call to Session is actually looking in Model\Session when it actually exists in \Fuel\Core\Session
There are two ways around this. You've demonstrated an example yourself in your question with a call to the use language construct.
use DB;
This causes PHP to search for classes in this namespace as well as the one which is already being used (Model in this case).
The other way you can do it is by calling the class with the explicit namespace. For example
\Fuel\Core\Session::get();
Fuel also aliases all core classes to the root namespace for convenience. What this means is you can also directly call classes in \Fuel\Core just using \. For example
\Session::get();