I have TYPO3 version 7.6.18, I need add some property to model user
$public age = 0;
and I tried add different methods :
public setAge(){$this->age = 23;}
public age(){return $this->age;}
public getAge(){return $this->age;}
public age(){return 23;}
public getAge(){return 23;}
And on fluid I always get 0. {user.age} - I get 0. What is the problem ? May be because I have not field 'age' in DB table ? But I need add age property to user model without field in DB. Is it possible ? how to do it ?
First things first:
What user model are you talking about?
fe_user, beuser - or something completly different?
How did you tried to add these?
Have you created a custom class which extends the user class?
Greetings,
KamiYang
you must define your getter in this way:
public function getAge()
{
return 23;
}
In your examples you have forgot the function declaration.
If this don't work, check if the correct domain model is gotten.
Try to something like below.
/**
* #var Age
*/
protected $age = 23;
public function __construct($age) {
$this->setAge($age);
}
public function setAge($age) {
$this->age = $age;
}
public function getAge() {
return $this->age;
}
Related
I would like to extend the extension cart with a new field to put in the IBAN in the checkout.
So I created a new extension and added a database field with the following code in ext_tables.sql
#
# Table structure for table 'tx_cart_domain_model_order_item'
#
CREATE TABLE tx_cart_domain_model_order_item (
iban varchar(255) DEFAULT '' NOT NULL
);
Now I need to extend the class Item in
ext/cart/Classes/Domain/Model/Order/item.php
I tried to create a file in my extension
ext/cartextend/Classes/Domain/Model/Order/item.php
and tried to extend the class with:
namespace Extcode\Cart\Domain\Model\Order;
use Extcode\Cart\Property\Exception\ResetPropertyException;
class Item extends \Extcode\Cart\Domain\Model\Order
{
/**
* Iban
*
* #var string
*/
protected $iban;
/**
* #return string
*/
public function getIban()
{
return $this->iban;
}
/**
* #param string $iban
*/
public function setIban($iban)
{
$this->iban = $iban;
}
}
I also added an input field that is implemented correctly.
But the IBAN is not saved at all - i guess the extending of the class is wrong.
I really appreciate any hint.
Many thanks! Urs
Maybe you have to extend item.php like this (the rest looks fine):
namespace Extcode\YourExtension\Domain\Model\Order;
class Item extends \Extcode\Cart\Domain\Model\Order\Item
and do not forget to make it known to extbase for you to use iban in the front-end trough typoscript: (I have it to extend cart_products, you'll have to adept it)
config.tx_extbase {
persistence {
classes {
Extcode\CartExtendedProduct\Domain\Model\Product\Product {
mapping {
tableName = tx_cartproducts_domain_model_product_product
recordType =
}
}
}
}
objects {
Extcode\CartProducts\Domain\Model\Product\Product.className = Extcode\CartExtendedProduct\Domain\Model\Product\Product
}
}
I'm using Symfony2 validation getters to validate if endDate is later than startDate. It works fine except that I want the error to appear for endDate field not above the whole form. All other validation errors appears above the field it validates. Is there any way to do that?
validation part in my Entity:
/**
* #Assert\True(message = "Invalid date")
*/
public function isDatesValid()
{
return ($this->startDate < $this->endDate);
}
I don't think there is a way to achieve that with a getter validation.
Instead you could use a custom constraint: http://symfony.com/doc/current/cookbook/validation/custom_constraint.html
You'll need to overide the getTargets() method in order to access all properties:
class DateRangeConstraint extends Constraint {
public $message = 'Your message';
public function getTargets() {
return Constraint::CLASS_CONSTRAINT;
}
}
class DateRangeConstraintValidator extends ConstraintValidator {
public function validate($obj, Constraint $constraint) {
if ($obj->startDate() < $obj->endDate()) {
$this->context->addViolationAt(
'startDate',
$constraint->message,
array(),
null
);
}
}
}
Assign this constraint to one or both properties.
I have some simple objects
public class DataClass
{
public int id;
public string Data;
}
public class Job()
{
public int id;
}
public class NewJob : Job
{
public DateTime StartDate;
public DataClass data;
}
I have then defined them in my dBContext()
public DbSet<Job> Jobs { get; set; }
public DbSet<DataClass> DataClass { get; set; }
Now if I use the following code
NewJob job = (NewJob) db.Jobs.Find(id);
This works fine but returns "data" as null
I know I define the class with the virtual keyword and it works and populates the "data" object.
public class NewJob : Job
{
public DateTime StartDate;
public virtual DataClass data;
}
But in my case I "normally" do not want the "data" object to be populated. So I need to load it on demand.
If I try something like
NewJob job = (NewJob)db.Jobs.Include("data").First();
I get an exception
A specified Include path is not valid. The EntityType 'Models.Job' does not declare a navigation property with the name 'data'.
I guess this is because it is looking at "job" and not "NewJob" when it is trying to do the include.
I also do not like the include with a string - no design time checking.
It looks like you are trying to convert data object to your domain object via type casting which is a very bad idea. What you want to do is grab your data object, instantiate your domain object, and map your data values to the domain object using some type of helper class. A very helpful tool I have been using is Automapper. Its a tool that will allow you to map one object to another. It also allows the use of regular expression to help with the mappings if the naming conventions between the 2 objects are different.
If you're using Entity Framework Code First and want to create instances of derived classes/entities you should do the following:
using (var db = new MyDbContext())
{
var newJob = db.Jobs.Create<NewJob>();
newJob.data.Data = "some data for a new job"; // this is string Data from DataClass
db.Jobs.Add(newJob);
db.SaveChanges();
}
After a lot of searching I found the following which can help.
If you include the System.Data.Entity namespace in your using clause then you can use the extension method .Include() after OfType<>() which is not normally available.
Slightly different code sample
using System.Data.Entity;
NewJob job = (NewJob)db.Jobs.OfType<NewJob>().Include(m => m.data).Where(x => x.id == id).FirstOrDefault();
This seems to be working for me in the example I used.
I am working on Entity Framework 4.0 POCO and looking for a way to sort my grid on the list page with a field other than the primary key in the table/entity. I do not want to add a custom page though it is one of the solutions as that would be an overhead if this can be done otherwise.
Thanks in advance.
If the result you are getting back is something like IEnumerable< YourPocoClass > or IQueryable< YourPocoClass >, you can always use .OrderBy(p => p.SomePropertyOtherThanPK)
You could just do this :
var list = yourDbContext.YourDbSet.OrderBy(m=>m.Property);
Or if you wanna sort by string comes from the grid form by the client then you may use the Dynamic Linq:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Solved the issue with the following attribute.
I added a new attribute class for adding the sort column - DefaultSortOrderColumn
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class DefaultSortColumnAttribute : Attribute
{
public DefaultSortColumnAttribute(string sortColumn, bool sortDescending)
{
this.SortColumn = sortColumn;
this.SortDescending = sortDescending;
}
public string SortColumn { get; private set; }
public bool SortDescending { get; private set; }
}
Then using this attribute for the partial entity class, i.e. the metadata class of your entity, for which we need to use the sort column
[DefaultSortColumn("YourSortColumn", false)]
public partial class YourDBEntity
{
}
We can then use this attribute in the PageTemplates\List.aspx to determine if there are any sortcolumns defined and sort with that in Page_Load.
MetaTable table = GridDataSource.GetTable();
if (!IsPostBack && table.Attributes.OfType<DefaultSortColumnAttribute>().Count() > 0)
{
string sortColumn = table.Attributes.OfType<DefaultSortColumnAttribute>().FirstOrDefault().SortColumn;
bool sortDescending = table.Attributes.OfType<DefaultSortColumnAttribute>().FirstOrDefault().SortDescending;
GridView1.Sort(sortColumn, sortDescending ? SortDirection.Descending : SortDirection.Ascending);
}
This attribute can further be extended and set to the properties instead of the class. That way, we would be able to sort on multiple columns.
Thanks to those reponded. Happy coding.
Is it possible to use doctrine on existing entity models like:
class user{
protected $_id;
protected $_name;
public function set_id($_id){}
public function get_id(){}
public function set_name($_name){}
public function get_name(){}
}
or to generate or use models with hard-coded getters and setters.
I dont want to use
$user->name
$user['name']
$user->get('name')
can this be done with doctrine?
Thanx
For all Versions up to Doctrine 1.2:
Your entity models class needs to extend the Doctrine_Record class.
The definition of the model fields needs to be done the "doctrine way" too.
See: http://www.doctrine-project.org/documentation/manual/1_2/en/defining-models
example:
public function setTableDefinition()
{
$this->hasColumn('username', 'string', 255);
$this->hasColumn('password', 'string', 255);
}
If you want to use your own custom hard coded setters/getters you can override the magic getters/setters.
See: http://www.doctrine-project.org/documentation/manual/1_2/en/introduction-to-models
example:
class User extends BaseUser {
public function setPassword($password)
{
return $this->_set('password', md5($password));
}
}
One last remark/question: Using the magic setter/getter methods is good practise.. You should only use custom methods, if you need to manipulate the data in some way.