I have two DataObjects on Silverstripe 4.
First a Quiz whith a has_many-relationships with the questions for that Quiz.
use SilverStripe\ORM\DataObject;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\DateField;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\CheckboxField;
class Quiz extends DataObject {
private static $db = [
"Name" => "Varchar(200)",
"bis" => "Date()",
"aktiv" => "Boolean",
"Mail" => "Boolean",
"MailText" => "Text"
];
private static $has_one = [
];
private static $has_many = [
"Fragen" => Quiz_Fragen::class
];
The code for the questions.
use SilverStripe\ORM\DataObject;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\TextareaField;
class Quiz_Fragen extends DataObject {
private static $db = [
"Frage" => "HTMLText",
"Art" => "Enum(array('auswählen','MC','Text','Check'))",
"OP1" => "Varchar(400)",
"OP2" => "Varchar(400)",
"OP3" => "Varchar(400)",
"OP4" => "Varchar(400)",
"Foul" => "Varchar(50)",
"Team" => "Enum(array('A','B'))",
"Punkte" => "Varchar(200)",
"Down" => "Enum(array('1','2','3','4','Try','FK'))",
"Pos" => "Varchar(25)",
"Distanz" => "Varchar(2)",
"Uhr" => "Enum(array('Snap','Ballfreigabe','Down ohne Zeit','keine','läuft'))",
"Sonstiges" => "Varchar(50)",
"Antwort" => "HTMLText",
"SortOrder" => "Int",
"Grund" => "HTMLText",
"Pkt" =>"Enum(array('1','2','3','4','5','6','7','8','9','10','11','12'))"
];
private static $has_one = [
"Quiz" => Quiz::class
];
private static $has_many = [
];
In Silverstripe 3 I chose a entry of the dataobject quiz an had a link on the top to see the questions related to the chosen quiz. I miss this link in Silverstripe 4. I'm sure I'm just missing a little thing. But I can't find a solution.
It was the FieldList.
On the dataobject Quiz I added the fields this way.
$fields = FieldList::create(
TextField::create('Name','Name des Quiz'),
DateField::create('bis','Quiz läuft bis'),
LiteralField::create("Text", "Vor der Aktivierung die Fragen eintragen. Sobald aktiviert wird bekommen die Benutzer eine E-Mail.<br /><br />"),
CheckboxField::create('aktiv', 'Quiz aktivieren')
);
When I use the old way of my SS 3 version. It works. So the problem is solved.
Related
Sorry not the best title.
I am building an application with many different classes that will be called by a document builder class that takes an Array of what are defined as segments that are then used to reference the segments class to then be built into the document. I provided the Document class and the SegmentConfig file that references which segment points to which file location.
Reference Below First
I could not find a definitive answer on how I could use this to then generate the segment object
could I do it like use $segmentObjectLocation as it would be equal to something like 'Edi\Segments\AmtSegment'. If anyone has some insight.
Other info: the reason I am trying to do it some way like this is becuase this will be used in multiple places though out the application.
$segmentLocation = include('SegmentConfig.php');
class Document{
public function __construct($structure){
$this -> documentStructure = $structure;
foreach($structure as $segment){
buildSegment($segment);
}
}
public function buildSegment($segment){
$segmentObjectLocation = $segmentLocation ->{$segment};
}
}
<?php
namespace Edi;
SegmentConfig.php
return (object) array(
'AMT' => 'Edi\Segments\AmtSegment',
'B4' => 'Edi\Segments\B4Segment',
'BEG' => 'Edi\Segments\BegSegment',
'CTT' => 'Edi\Segments\CttSegment',
'DTM' => 'Edi\Segments\DtmSegment',
'FOB' => 'Edi\Segments\FobSegment',
'GE' => 'Edi\Segments\GeSegment',
'GS' => 'Edi\Segments\GsSegment',
'IEA' => 'Edi\Segments\IeaSegment',
'ISA' => 'Edi\Segments\IsaSegment',
'MSG' => 'Edi\Segments\MsgSegment',
'N1' => 'Edi\Segments\N1Segment',
'N2' => 'Edi\Segments\N2Segment',
'N3' => 'Edi\Segments\N3Segment',
'N4' => 'Edi\Segments\N4Segment',
'N9' => 'Edi\Segments\N9Segment',
'PER' => 'Edi\Segments\PerSegment',
'PID' => 'Edi\Segments\PidSegment',
'PO1' => 'Edi\Segments\Po1Segment',
'Q2' => 'Edi\Segments\Q2Segment',
'R4' => 'Edi\Segments\R4Segment',
'REF' => 'Edi\Segments\RefSegment',
'SAC' => 'Edi\Segments\SacSegment',
'SE' => 'Edi\Segments\SeSegment',
'ST' => 'Edi\Segments\StSegment',
'TC2' => 'Edi\Segments\Tc2Segment',
'TD1' => 'Edi\Segments\Td1Segment',
'TD4' => 'Edi\Segments\Td4Segment',
'TD5' => 'Edi\Segments\Td5Segment',
)
Not that this sounds like a particularly great idea, but:
class Foo {}
$n = 'Foo';
$f = new $n();
var_dump($f);
Output:
object(Foo)#1 (0) {
}
I am working on an Online Store and want to insert some payment details into payments table.
Everything works good except this insertion process that does insert data into table:
if (!empty($existPayment)) {
$existPayment->delete();
$payment = Payment::create([
'pay_type_id' => '186',
'pay_date' => jdate()->format('Y/m/d'),
'pay_amount' => $order->ord_total * 10,
'pay_ord_id' => $order->ord_id,
'pay_status_id' => '182',
'pay_creator_id' => auth()->user()->usr_id,
'pay_confirm' => '1',
]);
}
So in order to know where the problem is coming from, I tried this:
if (!empty($existPayment)) {
dd('Exists');
}
And I got the result Exists, then I tried:
if (!empty($existPayment)) {
if($existPayment->delete()){
dd('Deleted');
}
}
And again I got the correct result which is Deleted, after that I tried:
if (!empty($existPayment)) {
$existPayment->delete();
$payment = Payment::create([
'pay_type_id' => '186',
'pay_date' => jdate()->format('Y/m/d'),
'pay_amount' => $order->ord_total * 10,
'pay_ord_id' => $order->ord_id,
'pay_status_id' => '182',
'pay_creator_id' => auth()->user()->usr_id,
'pay_confirm' => '1',
]);
dd($payment);
}
And I got this as result:
"pay_type_id" => "186"
"pay_date" => "1400/05/05"
"pay_amount" => 750000.0
"pay_ord_id" => 9222
"pay_status_id" => "182"
"pay_creator_id" => 2
"pay_confirm" => "1"
"updated_at" => "2021-07-27 12:12:06"
"created_at" => "2021-07-27 12:12:06"
"pay_id" => 8929
But when I check the DB, the data is not inserted somehow and I don't know why!
I also put this code in try..catch but didn't show any kinds of error.
So if you know how to solve this issue or any idea on how to debug it, please let me know...
I would really appreciate that.
Thanks in advance.
MODEL:
class Payment extends Model
{
use SoftDeletes;
protected $table = "payments";
protected $primaryKey = "pay_id";
protected $guarded = [];
protected $appends = [
'status_label', 'type_label'
];
protected $fillable = [
'pay_type_id ','pay_date','pay_amount','pay_ord_id','pay_status_id','pay_creator_id','pay_confirm' // all the columns you want
];
...
Try This
$payment = new Payment;
$payment->pay_type_id = '186';
$payment->pay_date = jdate()->format('Y/m/d');
$payment->pay_amount = $order->ord_total * 10;
$payment->pay_ord_id = $order->ord_id;
$payment->pay_status_id = '182';
$payment->pay_creator_id = auth()->user()->usr_id;
$payment->pay_confirm = '1';
$payment->save();
You can Also Use an Easy Way By Using Fillable
For that In Your Payment Model add
protected $fillable = [
'pay_type_id ','pay_amount ' // all the columns you want
];
And use the Create method Mentioned In the Question
$payment = Payment::create([
'pay_type_id' => '186',
'pay_date' => jdate()->format('Y/m/d'),
'pay_amount' => $order->ord_total * 10,
'pay_ord_id' => $order->ord_id,
'pay_status_id' => '182',
'pay_creator_id' => auth()->user()->usr_id,
'pay_confirm' => '1',
]);
Note the Model Must be imported In Controller use App\Payment;
Im trying to extend https://github.com/Quadra-Digital/silverstripe-schema to be able to better handle nested schemas. I've managed to get it working all though it breaks one of the very useful features Dynamic Values.
It currently uses a DataObject called RelatedObject to map its related object which works fine when there is only one level of nesting. However once you get further into it and have SchemaInstances nested upon SchemaPropertys you lose the overarching owner, and the RelatedObject becomes the Property that the Instance is nested under.
class SchemaInstance extends DataObject {
private static $db = [
'ParentClass' => 'Varchar(255)'
];
private static $has_one = [
'RelatedObject' => 'DataObject',
'Schema' => 'Schema',
];
private static $has_many = [
'Properties' => 'SchemaProperty'
];
class SchemaProperty extends DataObject {
private static $db = [
'Title' => 'Varchar(255)',
'ValueStatic' => 'Varchar(255)',
'ValueDynamic' => 'Varchar(255)'
];
private static $has_one = [
'ParentSchema' => 'SchemaInstance'
];
private static $has_many = [
'NestedSchemas' => 'SchemaInstance'
];
This is what is currently saved when I created the nested schema instance.
52 SchemaInstance 2018-03-04 04:28:38 2018-03-04 04:28:38 0 File 8 0 96 SchemaProperty
I need it to look like this
52 SchemaInstance 2018-03-04 04:28:38 2018-03-04 04:28:38 0 File 8 0 96 *ActualParentClass*
I have tried getting the owner in the SchemaObjectExtension (Which works fine, I just can't figure out how to use that rather than the default)
class SchemaObjectExtension extends DataExtension {
private static $has_many = [
'SchemaInstances' => 'SchemaInstance.RelatedObject',
];
I'd be happy with just being able to save the owner class to the db somehow and the reference that. I've tried getting it from the DataObject but it gives a
"getOwner() is not a method on Dataobject" error.
Thanks for any help
I have got stuck on Multilevel associated tables in Cake PHP code.
I have the following models
Guardian who has many students and the various students have their studentfees. When I create a guardian with 2 students, an associated 2 row must be created for StudentFees table. Im successful in adding 2 students when adding a guardian, but I dont know how to add the 2 rows of fees for the student. My code is as below.
class Guardian extends AppModel {
public $name = 'Guardian';
public $recursive =2;
public $hasMany = array(
'Student' => array(
'className' => 'Student',
'dependent' => true
)
);
}
class Student extends AppModel {
public $name = 'Student';
public $hasMany = array(
'StudentFee' => array(
'className' => 'StudentFee',
'dependent' => true
)
);
}
class StudentFee extends AppModel {
public $name = 'StudentFee';
public $belongsTo = array(
'Student' => array(
'className' => 'Student',
'dependent' => true
)
);
}
Pl help me to save the studenFee details too. I use SaveAssociated function that saves guardian and Student details.
If I understood you correctly, this should do the trick:
Model::saveAll() should take care of it for you and select the appropriate method, saveMany or saveAssociated. Moreover, it will automatically set your foreignKeys so everything is neatly inserted into the database.
$this->Guardian->saveAll(array('Guardian' => array(
[...],
'Student' => array(
0 => array(
[here's your first Student],
'StudentFee' => array(
0 => array(
[here's your first StudentFee]
)
)
)
)
)));
can use saveAll and saveAssociated methods.
You can try using this method, which i always use in such situations :
$this->Studentfee->create();
$this->Studentfee->set(array(
'field1' => 'value',
'field2' => 'value'
));
$this->Studentfee->save();
and you can put in a loop for all student fees
I have the following, for example:
class Model_User extends ORM {
protected $_rules = array(
'username' => array(
'not_empty' => NULL,
'min_length' => array(6),
'max_length' => array(250),
'regex' => array('/^[-\pL\pN_#.]++$/uD'),
),
'password' => array(
'not_empty' => NULL,
'min_length' => array(5),
'max_length' => array(30),
),
'password_confirm' => array(
'matches' => array('password'),
),
);
}
class Model_UserAdmin extends Model_User {
protected $_rules = array(
'username' => array(
'not_empty' => NULL,
'min_length' => array(6),
'max_length' => array(250),
'regex' => array('/^[-\pL\pN_#.]++$/uD'),
),
'password' => array(
'not_empty' => NULL,
'min_length' => array(5),
'max_length' => array(42),
),
);
}
In here, Model_UserAdmin extends Model_User and overrides the max length for password and removes the validation for password_confirm (this is not an actual case, but an example).
Is there a better way instead of redefining the entire $_rules property/array?
Use _initialize() instead of __construct($id) if you want to store your UserAdmin model in session (like Auth module does). Serialized ORM objects will not call __construct(), so part of your rules will lost. _initialize() method sets default values for model properties like table_name, relationships etc
protected function _initialize()
{
// redefine model rules
$this->_rules['password']['max_length'] = 42 ;
unset($this->_rules['password_confirm']) ;
// call parent method
parent::_initialize();
}
In the child's constructor you can probably overwrite or add array elements to $this->_rules, as it will already exist as soon as you create a Model_UserAdmin instance.
Specifically, in Model_UserAdmin don't define a protected $rules so it gets it from its parent, and then in the constructor:
$this->_rules['password']['max_length'] = 42 ;
unset($this->_rules['password_confirm']) ;
You can also add some sanity check right before to make sure those keys exist, in case you change them in Model_User and forget.
It's not exactly elegant but it should work. I do suppose you can create some wrapper functions around it (probably in a class ORM extends ORM_Core so they're available when you extend ORM) that modify the rules in a more formal way.
edit please look at biakaveron's answer for a tip on where to place the child rules (_initialize() instead of the constructor)