JMS unserialize to-many relation does not remove with orphanremoval - doctrine-orm

I have a Symfony rest api build with fos restbundle and I'm deserializing a json PUT request in order to update a doctrine entity with a to-many relation.
However, the to-many child objects which are configured with orphanremoval=true does not get removed from the database when they are not present in the json data.
The PUT request payload:
{
"id": 1,
"name":"Some name",
"export_destinations": [
{
"id": 1,
"type": "USER_STORAGE",
"user": {"id": 5}
}
{
"id": 2,
"type": "SYSTEM_STORAGE"
}
]
}
The controller action:
/**
* #Rest\Put("{id}")
* #ParamConverter(
* "exportJob",
* converter="fos_rest.request_body",
* options={"deserializationContext"={"groups"={"put"}}}
* )
* #Rest\View(serializerGroups={"details"})
* #param ExportJob $exportJob
* #return ExportJob
*/
public function putAction(ExportJob $exportJob)
{
$this->getManager()->persist($exportJob);
$this->getManager()->flush();
return $exportJob;
}
ExportJob entity
/**
* #ORM\Entity()
*/
class ExportJob
{
/**
* #var ArrayCollection|ExportDestination[]
*
* #ORM\OneToMany(targetEntity="ExportDestination", mappedBy="exportJob", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
*/
protected $exportDestinations;
/**
* #param ExportDestination $exportDestination
* #return $this
*/
public function addExportDestination(ExportDestination $exportDestination)
{
$exportDestination->setExportJob($this);
$this->exportDestinations->add($exportDestination);
return $this;
}
/**
* #param ExportDestination $exportDestination
* #return $this
*/
public function removeExportDestination(ExportDestination $exportDestination)
{
$this->exportDestinations->removeElement($exportDestination);
$exportDestination->setExportJob(null);
return $this;
}
}
JMS meta data
MyProject\ExportBundle\Entity\ExportJob:
exclusion_policy: ALL
properties:
id:
groups: ['list', 'details', 'put']
expose: true
name:
groups: ['list', 'details', 'put', 'patch', 'post']
expose: true
exportDestinations:
groups: ['details', 'put', 'patch', 'post']
expose: true
type: 'ArrayCollection<MyProject\ExportBundle\Entity\ExportDestination>'
I am using the DoctrineObjectConstructor
jms_serializer.object_constructor:
alias: jms_serializer.doctrine_object_constructor
public: false
Now when I leave out the second object from the export_destinations array in the json payload my exportJob in the controller action has only one exportDestination object in the array collection after deserialization.
But when I persist, I expect doctrine to remove the exportDestination from the database since I have orphanremoval=true.
What I think the problem is, is that the removeExportDestination() method never gets called during deserialization what should set the relation to null on the inversed side. If that doesn't happen it will not delete the entity since it's not become an orphan yet.
Is there a way that JMS will use the add/remove methods for ArrayCollections during deserialization?
I've also tried to use merge() instead of persist() but did not make any difference

You are right about that "the removeExportDestination() method never gets called during deserialization".
You could define the accessor property to do what you want:
exportDestinations:
groups: ['details', 'put', 'patch', 'post']
expose: true
type: 'ArrayCollection<AppBundle\Entity\ExportDestination>'
accessor:
getter: "getExportDestinations"
setter: "setExportDestinations"
and in ExportJob entity:
public function getExportDestinations()
{
return $this->exportDestinations;
}
public function setExportDestinations($exportDestinations)
{
// first detach existing related entities.
foreach ($this->exportDestinations as $exportDestination) {
$exportDestination->setExportJob(null);
}
$this->exportDestinations = $exportDestinations;
foreach ($exportDestinations as $exportDestination) {
$exportDestination->setExportJob($this);
}
}
so that during deserialization "setExportDestinations" is called and it takes care of the relation removal.
Having said that, I am not sure if you should use orphanremoval=true on the relation, as
orphanRemoval=true, even if you will remove given ExportDestination from one ExportJob, and then attach to another ExportJob, this ExportDestination will be deleted during persist, because the reference has been deleted.
I would suggest to remove it and find another way to delete "orphan" ExportDestination entities.

Related

How to use Entities Classes from Different Locations in CodeIgniter 4 using Doctrine 2

I am using CodeIgniter 4.x for my project. In my approach, I am using Module system for my project. My Module system is like below structure:
- App
- Modules
- ListMaster
- User
- Models
- Doctrine
- Entities
- User.php
- UserApp.php
- UserGroup
- Models
- Doctrine
- Entities
- Usergroup.php
- Budget
- Models
- Doctrine
- Entities
- Budget.php
In a simple word, I have designed to have my Modules under App/Modules folder. This Folder could consist a Module folder or a folder which will hold Modules. As I created two Modules App/Modules/ListMaster/User and App/Modules/ListMaster/Usergroup. My Entity Class Files will be located under ...Models/Doctrine/Entities folders.
I have downloaded Doctrine using Composer. My Composer is as follow:
{
"require": {
"doctrine/orm": "^2.3.3",
"doctrine/dbal": "^3.2",
"doctrine/annotations": "^1.14",
"symfony/yaml": "^5.4",
"symfony/cache": "^5.4"
},
"autoload": {
"psr-0": {"": "src/"}
},
}
I have created a Library file under App/Libraries which is as follow:
<?php
namespace App\Libraries;
//WE INCLUDING THE AUTOLOAD VENDOR
include_once dirname(__DIR__, 2) . '/vendor/autoload.php';
use Doctrine\Common\ClassLoader;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
// TO OBTAIN THE ENTITY MANAGER
class Doctrine
{
public $em;
public function __construct()
{
// Retrieving all paths leading to entities classes
$modulePath = APPPATH."Models/Doctrine/Entities";
$entitiesPath = glob($modulePath, GLOB_ONLYDIR);
$modulePath = APPPATH."Modules/*/Models/Doctrine/Entities";
$entitiesPath = array_merge($entitiesPath, glob($modulePath, GLOB_ONLYDIR));
$modulePath = APPPATH."Modules/*/*/Models/Doctrine/Entities";
$entitiesPath = array_merge($entitiesPath, glob($modulePath, GLOB_ONLYDIR));
$isDevMode = true;
$cache = null;
$useSimpleAnnotationReader = false;
// CONNECTION SETUP
$config = config("Database");
$connection_options = array(
'driver' => strtolower($config->doctrine['DBDriver']),
'user' => $config->doctrine['username'],
'password' => $config->doctrine['password'],
'dbname' => $config->doctrine['database'],
'host' => $config->doctrine['hostname']
);
$proxies_dir = APPPATH . 'Models/Doctrine/Proxies';
$config = Setup::createAnnotationMetadataConfiguration($entitiesPath, $isDevMode, $proxies_dir, $cache, $useSimpleAnnotationReader);
if (ENVIRONMENT === 'development') {
$config->setAutoGenerateProxyClasses(true);
} else {
$config->setAutoGenerateProxyClasses(false);
}
try {
$this->em = EntityManager::create($connection_options, $config);
} catch (\Doctrine\ORM\ORMException $e) {
log_message("Doctrine Exception : ", $e);
}
}
}
As you can see from this, My Entities files will be at Models/Doctrine/Entities, Modules/{any folder}/Models/Doctrine/Entities, Modules/{any folder}/{any folder}/Models/Doctrine/Entities folders.
Now here is my sample Entities Class:
<?php
namespace entities;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User
{
/**
* #var smallint $id
*
* #ORM\Column(name="id", type="smallint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string $userName
*
* #ORM\Column(name="user_name", type="string", length=150, nullable=true)
*/
protected $userName;
/**
* Constructor
*/
public function __construct()
{
}
/**
* Get id
*
* #return boolean
*/
public function getId()
{
return $this->id;
}
/**
* Set userName
*
* #param string $userName
*/
public function setUserName($userName)
{
$this->userName = $userName;
}
/**
* Get userName
*
* #return string
*/
public function getUserName()
{
return $this->userName;
}
}
Now from my Controller I am executing this Line of code which produces entities\User class not found error. Though this structure can create and update Schema in Database successfully.
$users = $this->em->getRepository('entities\User')->findAll();
Please be noted that I have successfully Generate Proxy, Generate Entities, Crate Schema, Update Schema from this installation.
Thanks in Advance. Please let me know if I missed something to inform you.
So my question is, How to fix the class not found error and got result from Database from any table?

Symfony4 - Doctrine Cross Database joins configuration

I need cross database relations, i've read about this buti can't get what i want due to a mapping issue.
This is my situation
namespace App\Entity\Utility;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\Crm\User;
/**
* Description of Test
*
* #ORM\Table(name="fgel_utility.fgel_test")
* #ORM\Entity(repositoryClass="App\Repository\Utility\TestRepository")
*/
class Test
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
*
* #var User
*
* #ORM\ManyToOne(targetEntity="App\Entity\Crm\User")
* #ORM\JoinColumn(name="user_cod", referencedColumnName="AUCUT")
*/
protected $user = null;
public function getId()
{
return $this->id;
}
public function getUser(): User
{
return $this->user;
}
public function setId($id)
{
$this->id = $id;
return $this;
}
public function setUser(User $user)
{
$this->user = $utente;
return $this;
}
}
namespace App\Entity\Crm;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Table(name="crm.USER")
* #ORM\Entity(repositoryClass="App\Repository\FintelGasDati\AnuteRepository")
*/
class User
{
/**
*
* #ORM\Id
* #ORM\Column(name="AUCUT", type="integer", nullable=false)
*/
protected $codiceCliente;
# SOME CODE
}
My doctrine.yaml
doctrine:
orm:
default_entity_manager: default
entity_managers:
#################################
# Update schema only with this em
#################################
default:
connection: mssql_1
mappings:
Utility:
type: "annotation"
# The directory for entity (relative to bundle path)
dir: '%kernel.project_dir%/src/Entity/Utility'
prefix: 'App\Entity\Utility'
alias: Utility
mssql_crm:
connection: mssql_1
mappings:
Crm:
type: "annotation"
# The directory for entity (relative to bundle path)
dir: '%kernel.project_dir%/src/Entity/Crm'
prefix: 'App\Entity\Crm'
alias: Crm
So they are sharing the same connection (but a different em). The user of the connections has the privileges to read/write both databases (but only to alter schema to the fgel_utility DB. Both DB are stored in a SQL Server 2008.
When i'm tryin' to execute
php bin/console doctrine:schema:update --dump-sql
I get this error
The class 'App\Entity\Crm\User' was not found in the chain configured
namespaces App\Entity\Utility, FOS\UserBundle\Model
You can actually trick Doctrine to do cross-database join queries to MySQL/MariaDB, simply by prefixing the database name in the ORM\Table annotation of your entites :
// src/Entity/User.php
#ORM\Table(name="dbname.users")
This will be used by Doctrine in all the SELECT, JOIN statements.
That beeing said, using this solution, the DB_NAME from DATABASE_URL or any other values of your env files won't be used, which can lead to confusions (as the database name should be coupled to the connection, not the entity).
As you cannot resolve dynamic value in your ORM mappings, such as "#ORM\Table(name=%env(DBNAME)%.users"), but here is an exemple of how you can use the LoadClassMetadata event from Doctrine to do that job dynamically.
The class constructor takes the Entities namespace as a first argument, and the database name as the second argument.
When Doctrine runs the metadata loading, it will fire the callback method with the metadata class for each entity, onto which you can process and set the table name dynamically from theses values.
// src/DatabasePrefixer.php
class DatabasePrefixer implements EventSubscriber
{
private $namespace;
private $tablePrefix;
/**
* #param $namespace string The fully qualified entity namespace to add the prefix
* #param $tablePrefix string The prefix
*/
public function __construct($namespace, $tablePrefix)
{
$this->namespace = $namespace;
$this->tablePrefix = $tablePrefix;
}
public function getSubscribedEvents()
{
return ['loadClassMetadata'];
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
if ($this->namespace == $classMetadata->namespace) {
$classMetadata->setTableName(sprintf('%s.%s', $this->tablePrefix, $classMetadata->table['name']));
}
}
}
Supposing that you have a DB_NAME env variable, configure the class as a service in your config/services.yml, using the yaml resolving features of Symfony, and the event tagging to listen to the correct Doctrine event :
// config/services.yaml
services:
[...]
dbname.prefixer:
class: App\DatabasePrefixer
arguments:
$namespace: 'App\Entity'
$tablePrefix: '%env(DB_NAME)%'
tags:
- { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }
According to this https://github.com/doctrine/doctrine2/issues/6350 cross database joins between different entity managers (same connections) isn't supported.

Laravel 5: cookie set by custom Middleware not readable in Controller

I created a website with Laravel 5. In order to keep track of users that were referred to by some other website I use the following middleware that recognizes the referral by a request parameter and sets a cookie.
<?php
namespace App\Http\Middleware;
use Closure;
class AffiliateTrackingMiddleware {
public static $trackingCookieName = "refId";
public static $trackingURLParameter = "refId";
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
$response = $next($request);
if ($request->has(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter)) {
return $response->withCookie(cookie()->forever(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingCookieName, $request->get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter)));
}
return $response;
}
}
In my controller I would like to retrieve the value of the cookie. I implemented the following function for that. For the case that there is no cookie available I also check if there is a request parameter set to identify the referrer.
protected function getAffiliateId($request = null) {
$affiliateCookieValue = Cookie::get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingCookieName);
if (!empty($affiliateCookieValue)) {
return $affiliateCookieValue;
} else {
if ($request !== null) {
if (!empty($request->get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter))) {
$affiliateRequestValue = $request->get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter);
return $affiliateRequestValue;
} else {
$affiliateCookieValue = $request->cookie(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingCookieName);
return $affiliateCookieValue;
}
} else {
return "";
}
}
}
The strange thing now is that within the constructor of my controller I am able to retrieve the correct affiliate id by cookie. However, when I call the function getAffiliateId from within another function of my controller the cookie value remains empty.
Why is it not possible for me to retrieve the cookie value set up in the middleware from any function in my controller?
In my browser I can also see the cookie.
Thanks a lot in advance.
added: The code of the Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel {
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\AfterMiddleware::class,
\App\Http\Middleware\AffiliateTrackingMiddleware::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
Since you want to use your middleware inside of your web middleware, append your middleware at the end of web group middleware, like so:
'web' => [
...
\App\Http\Middleware\AffiliateTrackingMiddleware::class,
]
Also make sure that your cookies are not empty when the request hits your middleware

Symfony form, One-to-one relationship, one side can be null

I have a MainConfig entity that has One-to-one relationship with LedConfig entity. LedConfig can be null.
<?php
namespace ...
use Doctrine\ORM\Mapping as ORM;
...
/**
* #ORM\Entity
*/
class MainConfig
{
...
/**
* #ORM\OneToOne(targetEntity="...\LedConfig", cascade={"all"})
* #ORM\JoinColumn(name="led_config_id", referencedColumnName="id", nullable=true, unique = true)
*/
private $ledConfig = null;
...
}
<?php
namespace ...
use Doctrine\ORM\Mapping as ORM;
...
/**
* #ORM\Entity
*/
class LedConfig
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="float")
* #Assert\Type(type="float")
*/
private $lowerVoltageThreshold = 11.9;
/**
* #ORM\Column(type="float")
* #Assert\Type(type="float")
*/
private $upperVoltageThreshold = 12.85;
}
<?php
namespace ...;
use Symfony\Component\Form\AbstractType;
...
class MainConfigType extends AbstractType
{
...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(...)
->add('ledConfig', LedConfigType::class)
...
}
...
}
I am inserting a main config into a database automatically without using Symfony forms. So, if I set led config to null in the code - field led_config_id inside main config table is correctly set to NULL.
But, when I am updating the main config, I am using HTTP PUT request that is processed through Symfony forms.
I am using JSON, so request body looks like this:
{..., "ssid":"test","runningMode":"force_on","led_config":null, ...}
After the form is processed, property $ledConfig inside MainConfig entity is magically instantiated as LedConfig object with all properties set to NULL?!
And database update fails because it tries to save LedEnttiy with empty fields.
Why does it happen?
Can someone please help me and indicate what I did wrong?
EDIT:
I could hack it in the controller update action, after the form validation:
/**
* #Route("...")
* #Method("PUT")
*/
public function updateMainConfigAction($id, Request $request)
{
$requestData = \GuzzleHttp\json_decode($request->getContent(), true);
...
if (!$form->isValid()) {
throw $this->throwApiProblemValidationException($form);
}
if (empty($requestData['led_config'])) {
$mainConfig->setLedConfig(null);
}
$em = $this->getDoctrine()->getManager();
$em->persist($mainConfig);
$em->flush();
...
}
but that is kind of dirty...
There are the empty_data and the required options on Symfony's FormType.
The empty_data option has following behaviour:
when data_class is set and required option is true, then empty_data is new $data_class();
when data_class is set and required option is false, then empty_data is null;
when data_class is not set and compound option is true, then empty_data is empty array;
when data_class is not set and compound option is false, then empty_data is empty string.
The required option is true by default and the data_class is set on the ledConfig field, so when you left it empty, then new class is set to it. If you want the ledConfig field to be explicitly set to null when no value is selected, you can set directly the empty_data option.
In your case, you want the #2 scenario, so set required option to false and empty_data option set to null on ledConfig field:
...
$builder
->add(...)
->add('ledConfig', LedConfigType::class, array(
'required' => false
'empty_data' => null
))
...

Laravel user_id forign key not working

I am new to Laravel and I have multiple registration types I have tried to add a foreign key following the aravel 5.2 documentation and it keeps giving me errors any help would be greatly appreciated. I need to connect the registration of each type of user into the different registration types. Below I will post one of the three registration types that I have. If there is a way to only add the user information to the user table after there email has been verified that would be great. So in other words each registration (3x) I need them to fill out registration and only the user table info goes to the user table the rest would go to the other table but I want to two to be connected.
This is the migration file I am trying to get to work following the laravel 5.2 documents.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->boolean('active')->default(false);
$table->rememberToken();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('artists');
$table->foreign('user_id')
->references('id')->on('artists')
//->onUpdate('cascade')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
//$table->dropForeign('artists_user_id_foreign');
}
}
I also tried doing the same thing on the artists table and it did not work either keep getting a foreign constraint issue.
Ill need to do that process for each type of user account.
The controller is set up like this for artist
<?php
namespace App\Http\Controllers\Artist;
use App\User;
use App\Artist;
use App\Mailers\AppArtMailer;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class RegistrationController extends Controller
{
//protected $redirectTo = 'art';
/** Create a new registration instance.
*/
public function __construct()
{
//$this->middleware('artist');
}
/** show the Register page/
*
* #return \Response
*/
public function register()
{
return view('art.register');
}
/**
* Perform the registration.
*
* #param Request $request
* #param AppMailer $mailer
* #return \Redirect
*/
public function postRegister(Request $request, AppArtMailer $mailer)
{
//Validate
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:artists',
'password' => 'required'
]);
//create artist
$artist = Artist::create($request->all());
$user = User::create($request->all());
//email them
$mailer->sendEmailConfirmationTo($artist);
//$mailer->sendEmailConfirmationTo($user);
//flash
flash('Please confirm your email address.');
// redirect
return redirect()->back();
}
/**
* Confirm a user's email address.
*
* #param string $token
* #return mixed
*/
public function confirmEmail($token)
{
Artist::whereToken($token)->firstOrFail()->confirmEmail();
flash('You are now confirmed. Please login');
return redirect('artist');
}
}
I also followed the laracast ACL Roles and Permissions but am not sure how to integrate that into each of the user registrations so that each type automatically has the set roles.
Here are the different models I have each is a bit different since I am learning and playing.

Artist Model This will actually change since they can only be an artist if they are a viewer.
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use App\Http\Middleware\RedirectIfAuthenticatedArtist;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Artist extends Model implements AuthenticatableContract, CanResetPasswordContract
{
protected $table = 'artists';
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Boot the model.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(function($artist) {
$artist->token = str_random(30);
});
}
/**
* Set the password attribute.
*
* #param string $password
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
/**
* Confirm the user.
*
* #return void
*/
public function confirmEmail()
{
$this->verified = true;
$this->token = null;
$this->save();
}
}
This is my users model
<?php
namespace App;
use DB;
use Illuminate\Http\Response;
use App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use Cmgmyr\Messenger\Traits\Messagable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasRoles, Messagable;
//* The attributes that are mass assignable.
//*
// * #var array
// */
protected $fillable = [
'name', 'email', 'password',
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
// $user->roles
}
Sponsors Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
//use App\Http\Middleware\RedirectIfAuthenticatedSponsor;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Sponsor extends Model implements AuthenticatableContract, CanResetPasswordContract
{
protected $table = 'sponsors';
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Boot the model.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(function($sponsor) {
$sponsor->token = str_random(30);
});
}
/**
* Set the password attribute.
*
* #param string $password
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
/**
* Confirm the user.
*
* #return void
*/
public function confirmEmail()
{
$this->verified = true;
$this->token = null;
$this->save();
}
}
Viewer Model
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Cmgmyr\Messenger\Traits\Messagable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use App\Http\Middleware\RedirectIfAuthenticatedViewer;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Viewer extends Model implements AuthenticatableContract, CanResetPasswordContract
{
protected $redirectTo = 'viewer';
use Authenticatable, CanResetPassword, Messagable;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'viewers';
//protected $table = 'experience';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function experience()
{
return $this->hasOne('App\Experience');
}
public function awardExperience($points)
{
return $this->experience->award($points);
}
/**
* Boot the model.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(func