I have a problem and don't know the best practice to solve it.
I want to have a form for my core data. The core data is all versionable.
I solved it with a GUID, to know the togetherness of the versions.
So now I have two versionable entities AgeClass and HighscoreList that can have a many-to-many relationship. The relationship has to be versionable, too, so I created a ReferenceEntity RefAgeClassHighscoreList. Now I have relationships with extra columns
valid-from [and]
valid-to
But now I don't know how I should build my form.
When I edit an AgeClass, all current (valid) HighscoreList items should be show as a checkbox.
But when I build the edit form, the values must be bound with a RefAgeClassHighscoreList entity.
I hope you understand my problem.
AgeClass:
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\DSV\Core\BaseDSVCoreDataRepository")
* */
class AgeClass extends BaseDSVCoreData
{
/**
* #ORM\Column(type="integer")
* #NotBlank()
* #var int
*/
protected $minAge;
/**
* #ORM\Column(type="integer")
* #NotBlank()
* #var int
*/
protected $maxAge;
/**
* #ORM\OneToMany(targetEntity="RefAgeClassHighscoreList", mappedBy="ageClass", cascade={"persist"})
* #var PersistentCollection
*/
private $ageClassHighscoreLists;
/**
* AgeClass constructor.
*/
function __construct()
{
$this->setGuid(GuidHelper::generateGuid());
$this->setValidFrom(new \DateTime());
}
/**
* #return int
*/
public function getMinAge()
{
return $this->minAge;
}
/**
* #param int $minAge
* #return AgeClass
*/
public function setMinAge($minAge)
{
$this->minAge = $minAge;
return $this;
}
/**
* #return int
*/
public function getMaxAge()
{
return $this->maxAge;
}
/**
* #param int $maxAge
* #return AgeClass
*/
public function setMaxAge($maxAge)
{
$this->maxAge = $maxAge;
return $this;
}
/**
* #return array
*/
public function getAgeClassHighscoreLists()
{
if($this->ageClassHighscoreLists == null)
return array();
return $this->ageClassHighscoreLists->toArray();
}
/**
* #param PersistentCollection $valuationClasses
* #return AgeClass
*/
public function seAgeClassHighscoreLists($valuationClasses)
{
$this->ageClassHighscoreLists = $valuationClasses;
return $this;
}
/**
* #return HighscoreList[]
*/
public function getHighscoreLists()
{
return array_map(
function ($ageClassHighscoreList) {
/** #var RefAgeClassHighscoreList $ageClassHighscoreList */
return $ageClassHighscoreList->getHighscoreList();
},
$this->getAgeClassHighscoreLists()
);
}
/**
* #param RefAgeClassHighscoreList $ageClassHighscoreList
* #return $this
*/
public function addAgeClassHighscoreList($ageClassHighscoreList)
{
if (!$this->ageClassHighscoreLists->contains($ageClassHighscoreList)) {
$this->ageClassHighscoreLists->add($ageClassHighscoreList);
$ageClassHighscoreList->setAgeClass($this);
}
return $this;
}
}
HighscoreList
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\DSV\Core\BaseDSVCoreDataRepository")
* */
class HighscoreList extends BaseDSVCoreData
{
/**
* #ORM\OneToMany(targetEntity="RefAgeClassHighscoreList", mappedBy="highscoreList", cascade={"persist"})
* #var PersistentCollection
*/
private $ageClassHighscoreLists;
function __construct()
{
$this->setGuid(GuidHelper::generateGuid());
}
/**
* #return PersistentCollection
*/
public function getAgeClassReferences()
{
return $this->ageClassHighscoreLists;
}
/**
* #param PersistentCollection $valuationClasses
* #return AgeClass
*/
public function setAgeClassReferences($valuationClasses)
{
$this->ageClassReferences = $valuationClasses;
return $this;
}
/**
* #return AgeClass[]
*/
public function getAgeClasses()
{
return array_map(
function ($ageClassHighscoreList) {
/** #var RefAgeClassHighscoreList $ageClassHighscoreList */
return $ageClassHighscoreList->getAgeClass();
},
$this->ageClassHighscoreLists->toArray()
);
}
/**
* #param RefAgeClassHighscoreList $ageClassHighscoreList
* #return HighscoreList
*/
public function addAgeClassReference($ageClassHighscoreList)
{
if (!$this->ageClassHighscoreLists->contains($ageClassHighscoreList)) {
$this->ageClassHighscoreLists->add($ageClassHighscoreList);
$ageClassHighscoreList->setHighscoreList($this);
}
return $this;
}
}
}
RefAgeClassHighscoreList
/**
* #ORM\Entity()
* */
class RefAgeClassHighscoreList implements IVersionable
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(type="datetime")
*/
protected $validFrom;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $validTo;
/**
* #ORM\ManyToOne(targetEntity="AgeClass", inversedBy="highscoreListReferences")
* #ORM\JoinColumn(name="ageclass_id", referencedColumnName="id", nullable=FALSE)
*/
protected $ageClass;
/**
* #ORM\ManyToOne(targetEntity="highscoreList", inversedBy="ageClassReferences")
* #ORM\JoinColumn(name="highscorelist_id", referencedColumnName="id", nullable=FALSE)
*/
protected $highscoreList;
protected $hasChanges = false;
/**
* #see IVersionable
*/
public function getId()
{
return $this->id;
}
/**
* #see IVersionable
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #see IVersionable
*/
public function getGuid()
{
return null;
}
/**
* #see IVersionable
*/
public function setGuid($guid)
{
return $this;
}
/**
* #see IVersionable
*/
public function getValidFrom()
{
return $this->validFrom;
}
/**
* #see IVersionable
*/
public function setValidFrom($validFrom)
{
$this->validFrom = $validFrom;
return $this;
}
/**
* #see IVersionable
*/
public function getValidTo()
{
return $this->validTo;
}
/**
* #see IVersionable
*/
public function setValidTo($validTo)
{
$this->validTo = $validTo;
return $this;
}
/**
* #see IVersionable
*/
public function isValid()
{
return ($this->validTo == null);
}
/**
* #see IVersionable
*/
public function createNewVersion()
{
$newVersion = clone $this;
$newVersion->setValidFrom(new \DateTime());
return $newVersion;
}
/**
* #see IVersionable
*/
public function hasChanges()
{
return $this->hasChanges;
}
/**
* #return AgeClass
*/
public function getAgeClass()
{
return $this->ageClass;
}
/**
* #param AgeClass $ageClass
* #return RefAgeClassHighscoreList
*/
public function setAgeClass($ageClass)
{
$this->ageClass = $ageClass;
return $this;
}
/**
* #return HighscoreList
*/
public function getHighscoreList()
{
return $this->highscoreList;
}
/**
* #param HighscoreList $highscoreList
* #return RefAgeClassHighscoreList
*/
public function setHighscoreList($highscoreList)
{
$this->gighscoreList = $highscoreList;
return $this;
}
}
Well, you have a very recurrent and tedious problem. You can do an embed form with AgeClass and embedding a form for RefAgeClassHighscoreList type. In that embedded form you can have an attribute of type HighscoreList , the problem is that the default rendered component for what you need is a multi-select list of HighscoreList, you can see it putting the attribute multiple = true to the property of HighscoreList.
For transform that list to a check-box list you need to create a custom theme extending or adding new blocks to the default one provided by symfony. My advice is to create new widgets and rows for your specific form using the form name. You can find a lot of documentation about what I mention and need to get a small part of each one to do what you ask.
Hope all this clues help you.
Related
When registering, a user is created, but a subscription is not created in Stripe and the Trial period does not appear. What is the correct way to write the "createAndStartSubscription" function?
public function __construct(User $user)
{
$this->user = $user;
$this->invoiceService = new InvoiceService();
}
/**
* #param User $user
* #return SubscriptionService
*/
public static function user(User $user)
{
return new self($user);
}
/**
* #param array $options
* #return void
*/
public function createAndStartSubscription(array $options = [])
{
$this->createCustomer($options);
$this->newSubscription();
}
/**
* #param array $options
* #return \Stripe\Customer
* #throws \Laravel\Cashier\Exceptions\CustomerAlreadyCreated
*/
public function createCustomer(array $options = [])
{
return $this->user->createAsStripeCustomer($options);
}
/**
* #param $paymentMethod
* #return void
*/
public function addPaymentMethod($paymentMethod)
{
$this->user->addPaymentMethod($paymentMethod);
$this->user->updateDefaultPaymentMethod($paymentMethod);
}
/**
* #param $plan
* #param $paymentMethod
* #return void
* #throws \Laravel\Cashier\Exceptions\IncompletePayment
*/
public function newSubscription($plan, $paymentMethod)
{
$this->user->newSubscription('default', self::E_PLANS[$plan])
->trialDays(1)
->create($paymentMethod);
$this->user->subscription_type = $plan;
$this->user->save();
}
I really need help. Thanks to everyone who responded!
I am using laravel 8 framework as my backend for my android application and I want to output time the same way instagram shows time but each time I use carbon diffForHumans it shows 2hours from now and I want it to show 1 minute ago, just now, 2 weeks ago,2 hours ago.
here is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Carbon\Carbon;
class News extends Model
{
use HasFactory;
protected $table = "news";
protected $fillable = [
'title',
'image',
'body'
];
protected $casts = [
'created_at' => 'datetime:d-m-Y',
'updated_at' => 'datetime:d-m-Y'
];
protected $appends=['published'];
public function getPublishedAttribute(){
return Carbon::createFromTimeStamp(strtotime($this->attributes['created_at']) )->diffForHumans();
}
}
here is my controller
<?php
namespace App\Http\Controllers;
use App\News;
use Illuminate\Http\Request;
class NewsController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$allposts = News:://get()->sortByDesc(function($query){
// return $query->toArray(['id']);
//})->
all();
return response()->json(['newsitemlist' => $allposts], 200);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$allposts = News::find($id);
if (is_null($allposts)) {
return response()->json(['message' => "News not available"], 404);
}
return response()->json(['newsitemlist' => $allposts], 200);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$allposts = News::find($id);
if (is_null($allposts)) {
return response()->json(['message' => "News not available"], 404);
}
$allposts->delete();
return response()->json(['message' => "News Deleted Succesfully"], 200);
}
}
You can also use
public function getCreatedAtAttribute($value){
return Carbon::parse($value)->diffForHumans();
}
Based on Docs, this is what you need to do to modify created_at value. Its called Accessor
public function getCreatedAtAttribute($value){
return Carbon::createFromFormat('Y-m-d H:i:s', $value)->diffForHumans();
}
Also you can check more about Carbon API here
I have an entity contact
<?php
namespace App\Entity;
use App\Repository\ContactRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ContactRepository::class)
*/
class Contact
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=50)
*/
private $firstName;
/**
* #ORM\Column(type="string", length=50)
*/
private $lastName;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $dob;
/**
* #ORM\Column(type="string", length=50)
*/
private $email;
/**
* #ORM\Column(type="string", length=15)
*/
private $phone;
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getDob(): ?\DateTimeInterface
{
return $this->dob;
}
public function setDob(?\DateTimeInterface $dob): self
{
$this->dob = $dob;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(string $phone): self
{
$this->phone = $phone;
return $this;
}
}
I want to select one (or more) contact with this URL: /c00210/readallbyparam/{routeProperty}/{routeValue}
For example: /c00210/readallbyparam/lastname/Mendelsohn
This should return 2 records:
Felix Mendelsohn
Fanny Mendelsohn
How do I write the render() function?
How do I write the twig instructions?
I suppose I should use the metadata, but I don't know
+++++++++++++++++++++++++++++++++++++++
here is the function in my controller
/**
* #Route("/c00210/readallbyparam/{routeProperty}/{routeValue}", name="c00210_read_all_by_param")
*/
public function findAllByparam( $routeProperty,$routeValue)
{
$property = $routeProperty;
$value = $routeValue;
$repository = $this->getDoctrine()->getRepository(Contact::class);
$contacts = $repository->findAll();
return $this->render('c00210/readbycriteria2.html.twig', [
'function' => 'find(<id>)',
'description' => 'finds the with the given Id',
'property' => $property,
'value' => $value,
'contacts' => $contacts,
]);
routeProperty should be a column name, and routeValue a column value
shoud be equivalent to
SELECT * FROM contacts WHERE lastname = 'Mendelsohn'
I am trying to make 2 artisan commands that would each do a different task that should also be scheduled to do their tasks each day.
So far, I have set it up like this:
I have created a FolderImport class in the Console/Commands directory:
class FolderImport extends Command
{
protected $signature = 'import:folders';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Imports folders';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct(ImportController $folders)
{
parent::__construct();
$this->folders = $folders;
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$this->folders->scheduledImport();
}
}
And the ContentImport class:
class ContentImport extends Command
{
protected $signature = 'import:content';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Imports content';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct(ImportController $content)
{
parent::__construct();
$this->content = $content;
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$this->content->scheduledImport();
}
}
And then in the Kernel file I have added them like this:
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
Commands\Inspire::class,
Commands\ContentImport::class,
Commands\FolderImport::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('import:content')
->withoutOverlapping();
$schedule->command('import:folders')
->withoutOverlapping();
$schedule->call('App\Http\Controllers\ImportController#all')
->dailyAt('00:00');
$schedule->call('App\Http\Controllers\ImportController#folder')
->dailyAt('00:00');
}
}
How can I connect the import:folders command with the call to ImportController#folder and the command import:content to the call to ImportController#all?
I log in perfectly with the entity User. When I log in, I can get to user via Security.Context. Can I include another table, e.g. UserSettings to security.context? What I have to do in entity User.php.
My entity User.php:
<?php
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\Exception\DisabledException;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
* #UniqueEntity("email")
*/
class User implements AdvancedUserInterface, \Serializable {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
...
public function getId()
{
return $this->id;
}
...
My UserSettings.php:
<?php
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* UserSettings
*
* #ORM\Table(name="user_settings")
* #ORM\Entity
*/
class UserSettings
{
/**
* #var \Language
*
* #ORM\ManyToOne(targetEntity="Language")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="locale", referencedColumnName="id")
* })
*/
private $locale;
/**
* #var \User
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="id")
* })
*/
private $id;
/**
* Set locale
*
* #param \Frontend\AccountBundle\Entity\Language $locale
* #return UserSettings
*/
public function setLocale(\Frontend\AccountBundle\Entity\Language $locale = null)
{
$this->locale = $locale;
return $this;
}
/**
* Get locale
*
* #return \Frontend\AccountBundle\Entity\Language
*/
public function getLocale()
{
return $this->locale;
}
/**
* Set id
*
* #param \Frontend\AccountBundle\Entity\User $id
* #return UserSettings
*/
public function setId(\Frontend\AccountBundle\Entity\User $id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return \Frontend\AccountBundle\Entity\User
*/
public function getId()
{
return $this->id;
}
}