How to join these two tables to get results as api resource? - eloquent

am having two tables one is the main client table and the other one is a sub-client table, The sub-clients is a client of the main client that is the primary key of the main client is in sub-client table how can i join these two tables and take the output in controller to pass over the resource as JSON for API ??
This is my model of the main client :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Clients extends Model
{
//
}
This is my Controller of the main client :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Clients;
use App\Http\Resources\Client as ClientResource;
// use Illuminate\Http\Response;
class Clients_controller extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//get clients
$clients = Clients::paginate(15);
//Return collection of clients as a resource
return ClientResource::collection($clients);
}
}
This is my model of the Sub client :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sub_clients extends Model
{
//
}
This is my Controller of the sub-client :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Sub_clients;
use App\Http\Resources\Sub_client as SubclientResource;
class Sub_client extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//get Sub_clients
$subclients = Sub_clients::paginate(15);
//Return collection of sub clients as a resource
return SubclientResource::collection($subclients);
}
}
Can anyone please help since am new to laravel

I joined using Query Builder
$client = DB::table('clients')
->join('sub_clients', 'clients.c_id', '=', 'sub_clients.c_id')
->select('clients.*', 'sub_clients.password', 'sub_clients.username as name')
->where('sub_clients.c_id','=',$c_id)
->get();

Related

Deactivate the ID (older Table)?

I have an old table without an ID (without a primary key).
Now I have to insert a record via Laravel and I get an error message:
Error Code : 904 Error Message : ORA-00904: "ID": invalid ID position.
How can I deactivate the ID?
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Log extends Model
{
use HasFactory;
protected $connection = 'oracle_client_nonprefix';
protected $table = 'al_logs';
}
Use any of your existing columns as primary key and disable auto increment
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Log extends Model
{
use HasFactory;
protected $primaryKey = 'log_date';
protected $incrementing = false;
}

How to extend tx:cart with a new field in TYPO3?

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
}
}

[Symfony][Form] Add validator/constraint to property only if it has changed

I've got the following scenario: I'm validating appointments and there's a custom validator, which tells the user if his choosen date is valid or not. It's not valid, if the date is already blocked by another entity. This works flawlessly on adding new entities.
Now I'd like to trigger the date validation on edit only if the date itself has changed. So just changing the title of the appointment should not validate the date.
My entity class:
use Doctrine\ORM\Mapping as ORM;
use Acme\Bundle\Validator\Constraints as AcmeAssert;
/**
* Appointment
*
* #ORM\Entity
* #AcmeAssert\DateIsValid
*/
class Appointment
{
/**
* #ORM\Column(name="title", type="string", length=255)
*
* #var string
*/
protected $title;
/**
* #ORM\Column(name="date", type="date")
*
* #var \DateTime
*/
protected $date;
}
The validator class (used as a service):
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the date of an appointment.
*/
class DateIsValidValidator extends ConstraintValidator
{
/**
* {#inheritdoc}
*/
public function validate($appointment, Constraint $constraint)
{
if (null === $date = $appointment->getDate()) {
return;
}
/* Do some magic to validate date */
if (!$valid) {
$this->context->addViolationAt('date', $constraint->message);
}
}
}
The corresponding Constraint class is set to target the entity class.
use Symfony\Component\Validator\Constraint;
/**
* #Annotation
*/
class DateIsValid extends Constraint
{
public $message = 'The date is not valid!';
/**
* {#inheritdoc}
*/
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
/**
* {#inheritdoc}
*/
public function validatedBy()
{
return 'acme.validator.appointment.date';
}
}
Now I don't find a clean way to depend on a date change. I could simply track the old date in my entity, but that doesn't feel like a proper solution, if I'd like to implement more complex constraints. :[
Cheers
Since symfony 2.3 you can use Form Events to solve this problem. I added the change-check code to my FormType, by storing (and cloning) the original entity at the form creation.
Then added a POST_SUBMIT event listener to check if the fields were changed. The listener can add validation errors to your fields.
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormError;
use Acme\Bundle\Entity\Appointment;
class AppointmentType extends AbstractType
{
private $originalAppointment;
public function __construct(Appointment $original)
{
// save the original entity
$this->originalAppointment = clone $original;
}
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
// define your fields
$builder->addEventListener(FormEvents::POST_SUBMIT, [$this, 'dateCheckListener']);
}
public function dateCheckListener(FormEvent $event)
{
$appointment = $event->getData();
$form = $event->getForm();
// if no appointments exist, we can skip the check
if (empty($appointment) || empty($this->originalAppointment)) {
return;
}
if ($appointment->getDate() !== $this->originalAppointment->getDate()) {
// the dates changed, you can call your validator here
if ('dates are not valid') {
$form->get('date')->addError(new FormError('We have a problem.'));
}
}
}
}
In your controller, you can create this formType with the original appointment:
$appointment = $this->getYourAppointmentSomehow();
$form = $this->createForm(new AppointmentType($appointment), $appointment);
Maybe you will find this article useful, to check which property is changed. Everything is possible in symfony. You might end up writing entity listeners, listener resolvers and so on. Things can get ultra advanced.
http://docs.doctrine-project.org/en/latest/reference/change-tracking-policies.html
Pay attention to the setter method:
public function setData($data)
{
if ($data != $this->data) {
$this->_onPropertyChanged('data', $this->data, $data);
$this->data = $data;
}
}
Do you see the trick?:)
I would also use !== operator to also check variable type.
You can also simplify things. You dont need to call _onPropertyChanged, but call the function, which will set a property 'dateChanged' to true. Then use method:
public function getGroupSequence()
{
if($this->dateChanged)
{
return ['date_check'];
}
else
{
return false;
}
}
And also tell your class that it implements GroupSequenceProviderInterface.
You can then use the validation group in your validation.yml for example.
maybe you want to try it with a preUpdate-Listener instead of a custom validation constraint?
Section 10.5.4 in the doctrine documentation gives an example of a validation listener "ValidCreditCardListener".
i know this will not work for automagic form validation, but i think it's the fastest way atm.
edit:
another option could be to use #UniqueEntiy constraint for the date field of your Appointment class. this will not break form validation but will cause an additional database query (as far as i know)

Zend DB Table and Model one to one

I have class that representing model of user with foreign key with is id of picture .
class Model_User extends Model_AbstractEntity
{
protected $u_id;
protected $u_email;
protected $u_firstname;
protected $u_lastname;
protected $u_password;
protected $u_salt;
protected $u_created_at;
protected $u_updated_at;
protected $u_fb;
protected $u_status;
protected $u_r_id;
protected $u_p_id;
}
Class with is responsible for picture model look like this:
class Model_Picture extends Model_AbstractEntity
{
protected $p_id;
protected $p_created_at;
protected $p_updated_at;
protected $p_caption;
protected $p_name;
protected $p_basePath;
protected $p_available;
protected $p_u_id;
}
This is only model part with is getting data from database.
Foreing key is u_p_id and key in picture is p_id
My problem is that when doing select() by Zend db table it returning me data with foreign key but how can I know which part of return data is picture part to set the proper picture model.... how to do it in proper way no to do 2 queries one for user and second for picture to create 2 associative objects.
I'm talking now about relation ont to one but maybe will be one to many..
Typically your entity models will not exist in void they will exist in concert with some type of Data Mapper Model. The Mapper will typically be charged with gathering the data from whatever source is handy and then constructing the entity model.
For example I have a music collection that has an album entity:
<?php
class Music_Model_Album extends Model_Entity_Abstract implements Interface_Album
{
//id is supplied by Entity_Abstract
protected $name;
protected $art;
protected $year;
protected $artist; //alias of artist_id in Database Table, foreign key
protected $artistMapper = null;
/**
* Constructor, copied from Entity_Abstract
*/
//constructor is called in mapper to instantiate this model
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
/**
* Truncated for brevity.
* Doc blocks and normal getters and setters removed
*/
public function getArtist() {
//if $this->artist is set return
if (!is_null($this->artist) && $this->artist instanceof Music_Model_Artist) {
return $this->artist;
} else {
//set artist mapper if needed
if (!$this->artistMapper) {
$this->artistMapper = new Music_Model_Mapper_Artist();
}
//query the mapper for the artist table and get the artist entity model
return $this->artistMapper->findById($this->getReferenceId('artist'));
}
}
//set the artist id in the identity map
public function setArtist($artist) {
//artist id is sent to identity map. Can be called later if needed - lazy load
$this->setReferenceId('artist', $artist);
return $this;
}
//each album will have multiple tracks, this method allows retrieval as required.
public function getTracks() {
//query mapper for music track table to get tracks from this album
$mapper = new Music_Model_Mapper_Track();
$tracks = $mapper->findByColumn('album_id', $this->id, 'track ASC');
return $tracks;
}
}
In the mapper I would build the entity model like:
//excerpt from Model_Mapper_Album
//createEntity() is declared abstract in Model_Mapper_Abstract
public function createEntity($row)
{
$data = array(
'id' => $row->id,
'name' => $row->name,
'art' => $row->art,
'year' => $row->year,
'artist' => $row->artist_id,//
);
return new Music_Model_Album($data);
}
to use this method in a mapper method, might look like:
//this is actually from Model_Mapper_Abstract, b ut give the correct idea and will work in any of my mappers.
//this returns one and only one entity
public function findById($id)
{
//if entity id exists in the identity map
if ($this->getMap($id)) {
return $this->getMap($id);
}
//create select object
$select = $this->getGateway()->select();
$select->where('id = ?', $id);
//fetch the data
$row = $this->getGateway()->fetchRow($select);
//create the entity object
$entity = $this->createEntity($row);
//put it in the map, just in case we need it again
$this->setMap($row->id, $entity);
// return the entity
return $entity;
}
I have seen Entities and Mappers built in many different ways, find the method that you like and have fun.
A lot of code has been left out of this demonstration as it doesn't really apply to the question. If you need to see the complete code see it at GitHub.

select queries with Zend_DB_Table

I have a code something like following
class Application_Model_Company extends Zend_Db_Table_Abstract {
protected $_name = 'companies';
private $id;
private $name;
private $shortName;
private $description;
public static function getAllCompanies() {
$companyObj = new self();
$select = $companyObj->select()->order(array('name'));
$rows = $companyObj->fetchAll($select);
if($rows) {
$companies = array();
foreach($rows as $row) {
$company = new self();
$company->id = $row->id;
$company->name = $row->name;
$company->shortName = $row->short_name;
$company->description = $row->description;
$companies[] = $comapny;
}
// return Company Objects
return $companies;
}else
throw new Exception('Oops..');
}
}
I need to return Company Objects from getAllCompanies() function, But it returns Zend_Db_Table_Row Object. How do I correct this?
Your Model class shouldnt extend the table class. The table class is separate. Your Model should extend the row class if extending anything from Zend_Db at all. Also you shouldnt put retrieval methods on your Model classes directly, they would go on the table classes.
This is because in the paradigm youre trying to use here, a Model represents a single Row of data, the Table class represents the table as a repository of data, and the Rowset class represents a collection of Rows (or Models).
To properly implement what you are describing in your question you would do something like the following:
class Application_Model_DbTable_Company extends Zend_Db_Table_Abstract
{
// table name
protected $_name = 'company';
protected _$rowClass = 'Application_Model_Company';
// your custom retrieval methods
}
class Application_Model_Company extends Zend_Db_Table_Row
{
protected $_tableClass = 'Application_Model_DbTable_Company';
// custom accessors and mutators
}
However, using some kind of implementation of the Data Mapper pattern is whats actually recommended. Check out the Quickstart for a thorough tutorial on a simplified implementation.