Vanilla PHP, Order status class [INTERNET STORE PROJECT] - php

I need to write an order status class (file Status.php), which will contain certain statuses of an order in my internet store, which I am currently working on.
Desired statuses are:
-Pending (User still haven't confirmed items in the basket).
-Confirmed (User confirmed items in the basket as his order).
-Paid (User has paid for items he bought)
-Complete (Items were sent to user via post office)
It's probably very simple task, but I don't know how to start my work and build this class.
This is my Status.php code so far:
<?php
class Status {
private $id;
private $name;
function __construct() {
$this->id = -1;
$this->name = "";
}
function getId() {
return $this->id;
}
function getName() {
return $this->name;
}
function setName($name) {
$this->name = $name;
}
}
?>
Big thanks to everyone who helps under this post :).

but I don't know how to start my work and build this class.
The code you posted is not a class but some procedural code disguised as OOP. Let's assume I create an object of type Status:
$status = new Status();
Is this an object? What is the value of this new object? It looks like an object but it is just some empty memory. No data, no behaviour, just useless code.
The constructor of a properly implemented class constructs the object, prepares it for usage. When the constructor returns, the object must be fully set; no further $status->setId() and $status->setName() should be required.
This is how I suggest you to define your class:
class Status {
private $id;
private $name;
public function __construct($id, $name) {
// Validate arguments; an object must always be valid
if (! is_int($id) || $id <= 0) {
throw new InvalidArgumentException('$id must be a positive non-zero number.');
}
if (! is_string($name) || empty($name)) {
throw new InvalidArgumentException('$name must be a non-empty string.');
}
// The arguments are valid; go ahead and construct the object
$this->id = $id;
$this->name = $name;
}
}
Now let's create some Status objects:
$pending = new Status(1, 'pending');
$confirmed = new Confirmed(2, 'confirmed');
Depending on how you plan to use the properties of the objects, you will probably not pass the ID as argument to the constructor but generate it internally or use a fixed list of values.
Or you can go one step further, declare the properties and the constructor of class Status as protected and create one child class for each possible value of $status:
class Status {
protected $id;
protected $name;
protected function __construct($id, $name) {
// ...
}
// ...
}
class Pending extends Status {
public function __construct() {
parent::__construct(1, 'pending');
}
}
class Confirmed extends Status {
public function __construct() {
parent::__construct(2, 'confirmed');
}
}
class Paid extends Status {
public function __construct() {
parent::__construct(3, 'paid');
}
}
The properties are protected to allow the methods of the children classes access them (when they are private only the methods of class Status see them). The constructor is protected to prevent the creation of objects of type Status but allow the methods of the children classes (their constructors actually) invoke it. Always call the constructor of the parent class in the constructor of the child class.
This way, when you need to create an object that represents a status, all you have to do is:
$pending = new Pending();
$confirmed = new Confirmed();
// a.s.o.
Don't rush to add the "getters" (the methods that access the object properties and provides the to the client code) you defined in your code. Think what do you want to do with the values stored in a Status object and check if that code can stay in the Status class too. Put code specific to the "pending" status (f.e.) into the Pending class, not into the Status class.
If Status::$name is used only for display then you better implement __toString() instead of getName():
class Status {
// ...
public function __toString()
{
// It is vital here to enforce the type of $this->name into the constructor
// __toString() must return a string
return $this->name;
}
}
This way your code will look nice:
$pending = new Pending();
echo('The status is: '.$pending);
// Output:
// The status is: pending

Related

Use of __construct or setVar() [duplicate]

I have been searching for this online, but I can't seem to find something that is clear enough for me to understand. I have seen "similiar" questions on here about this in Java.
class animal{
private $name;
// traditional setters and getters
public function setName($name){
$this->name = $name;
}
public function getName(){
return $this->name;
}
// animal constructors
function __construct(){
// some code here
}
// vs
function __construct($name){
$this->name = $name;
echo $this->name;
}
}
$dog = new animal();
$dog->setName("spot");
echo $dog->getName();
// vs
$dog = new animal("spot");
Should I declare and access my private fields through setters and getters or through the constructor?
Which one is the best practice?
I understand the purpose of a constructor(maybe not), but what is the point of having a constructor if I can declare and access my private fields through setters and getters?
Please note...this is my first time using OOP with web development and PHP, and I'm trying to learn by getting my hands "dirty" by writing some code in order for me to understand certain things in OOP. Please keep it simple.
It is more a matter of semantics than best practice per say.
In your example, your buisness logic may determine that an animal always needs a name.
So it makes sense to construct the object with a name. If you do not want to allow
an animal's name to be changed, then you don't write a setter.
i.e.
class Animal
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
You may have other properties that an animal doesn't have to have, like an owner
that you only write a getter/setter for i.e.
class Animal
{
private $name;
private $owner;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setOwner($owner)
{
$this->owner = $owner
}
}
But if you find that you are always creating an animal with an owner at the same time
you may want to put that in the contructor signature for convenience
class Animal
{
private $name;
private $owner;
public function __construct($name, $owner = null)
{
$this->name = $name;
$this->owner = $owner;
}
public function getName()
{
return $this->name;
}
public function setOwner(Owner $owner)
{
$this->owner = $owner
}
public function getOwner()
{
return $this->owner;
}
}
If the owner is another class in your application, you can type hint that your constructor
needs an owner of a specific type (class). All of this is used to make it easier for you, or another developer to understand some of the requirements/logic behind your code - as well as potentially catching a bug here or there
class Owner
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
}
class Animal
{
private $name;
private $owner;
public function __construct($name, Owner $owner = null)
{
$this->name = $name;
$this->owner = $owner;
}
public function getName()
{
return $this->name;
}
public function setOwner(Owner $owner)
{
$this->owner = $owner
}
public function getOwner()
{
return $this->owner;
}
}
// Create a new owner!
$dave = new Owner('Farmer Dave');
// a standard php empty object
$otherObj = new \stdClass();
// Create a new animal
$daisy = new Animal('Daisy');
// Farmer dave owns Daisy
$daisy->setOwner($dave);
// Throws an error, because this isn't an instance of Owner
$daisy->setOwner($otherObj);
// Set up Maude, with Dave as the owner, a bit less code than before!
$maude = new Animal('Maude', $dave);
Should I declare and access my private fields through setters and getters or through the constructor?
In situations like this, I ask myself:
Why should I create a method just to hold a one line function? (+Constructor)
How painful is it going to be to refactor two, three, four, five or more getters/setters vs one constructor?(+Constructor)
How hard is it going to be to document two, three, four, five or more getters/setters vs one constructor?(+Constructor)
Is there going to be a default value which will be documented? (+Constructor)
Do I like documentation and expect people to read? (+Constructor)
Will the initial value be undefined?(+Setter)
Is there a set of equivalent forms (shorthand, international, nicknames) which will all be acceptable as syntatically correct for required arguments? (+Setter)
Is there a set of optional arguments with default values? (+Setter)
Is there a common need to stringify and parse the initial value? (+Setter)
Do I dislike documentation and expect people to experiment? (+Setter)
Which one is the best practice?
The Date object seems to be the most complex class in most languages, so its PHP implementation would be a good reference for best practices.
What is the point of having a constructor if I can declare and access my private fields through setters and getters?
A constructor is implicitly invoked upon object instantiation in order to encapsulate the default state of the resulting data structure of its type.
References
DateTime::__construct
date_create
The DateTime class
date_default_timezone_get
date_default_timezone_set
Changes in PHP datetime support
PHP OOP: Accessor and Destructor Methods
Concurrency, part 4: Comparing promises frameworks in different languages – SLaks.Blog
CDD: Context-Driven Development
Depends. Usually one say: If it's a required dependency, use the constructor, if it's optional, use getter/setter.
There is no preference for, or against one of them.
The constructor contains code, that is executed right after the object is created and it should leave the object in a stable and useable state. Thats the idea behind the constructor and it doesn't work in any case, but it should give you an idea, what should go into it.
Note, that you can even implement both constructor arguments and setters for the same property, for example if you want to allow to replace property later.
$bingo = new Dog;
echo $bingo->getName(); // DogHasNoNameException <-- maybe better as constructor argument?
$bingo = new Dog('Bingo');
echo $bingo->getName(); // "Bingo"
$spike = new Dog; // Missing argument
$bingo->setName('Spike'); // Or maybe "rename()" ;)
echo bingo->getName(); // "Spike"
Should I declare and access my private fields through setters and
getters or through the constructor? Which one is the best practice?
Both. It depends on your needs. If need a value in certain fields you add a param to the
__construct()-Method to do so. Or you can also add an optional Param to __construct to give the user the option to set the attribute
I understand the purpose of a constructor(maybe not), but what is the
point of having a constructor if I can declare and access my private
fields through setters and getters?
The contructor should initialize your attributes which need to be initialized.
In my opinion, it is more correct to write setter's & getter's, since then, the number of properties will only grow. And the __construct can then take an array of properties of the names of the keys (property => value), and set them to properties.
1 > That's your chose : if dependency is required, good practise use the constructor, else, use getter.
2 > for the best practise is the first,
Actually, you have a name, for your animal, but if you add a type and sex? and you want to call type, sexe or name separatly, first method is more better than the second.
class animal{
private $name, $type, $sex;
// traditional setters and getters
public function setName($name){
$this->name = $name;
}
public function setSex($sex){
$this->sex = $sex;
}
public function setType($type){
$this->type = $type;
}
public function getName(){
return $this->name;
}
public function getSex(){
return $this->sex;
}
public function getType(){
return $this->type;
}
// animal constructors
function __construct(){
// some code here
}
}
$dog = new animal();
$dog->setName("spot");
$dog->setSexe("male");
$dog->setType("dog");
echo $dog->getName().' is a '.$dog->getType().'('.dog->getSex().')';
3 > that depends first question... BUt Globaly we are always one dependency required, for sample:
class animal{
private $name, $type, $sex;
// traditional setters and getters
public function setName($name){
$this->name = $name;
}
public function setSex($sex){
$this->sex = $sex;
}
private function setType($type){
// if type is string ( cat, dog, lion ) and you want
// to linked string in an id in your database (1, 2, 3...).
// you want to call your database connection ( declared in you constructor)
// and search type id here.
$this->type = $type;
}
public function getName(){
return $this->name;
}
public function getSex(){
return $this->sex;
}
public function getType(){
return $this->type;
}
// animal constructors
public function __construct($type){
// for sample you want to open your database here
this->setType($type);
}
public function __destruct(){
// and you want to close your connection here.
}
}

Unserialized object can't be passed from origin?

So I have a complex object which I wish to cache after creation as it is expensive to initialize. I'm able to reconstitute an instance within the class defining file but I need to be able to return the reconstituted instance in place of a new MyClass if my scheme is going to be of any use. (Don't I?)
Here's what I've done so far:
class PayPeriodService
{
public $type; // weekly,bi-weekly, semi-monthly, monthlly
public $payday_first;
public $close_first;
public $hours_start;
public $hours_end;
public $length; // in days
public $periods; // array of all periods this year
public $dayInterval;
public $oneWeekInterval;
public $twoWeekInterval;
public $semiFirstInterval;
public $monthInterval;
public $initialYear;
public $today; // date object
public function __construct()
{
if( Redis::exists('pay-period-instance')) {
Log:info( 'Fetching Pay-Period from cache.');
$instance = json_decode(Redis::get('pay-period-instance'));
// var_dump( $instance );
// exit();
return $instance;
}
return $this->init();
}
public function init()
{
Log::info('Reconstituting Pay-Period from primitive definition.');
$ppdef = PayPeriod::all()->last();
// etc etc etc, setting up all the properties, loading arrays etc
// finally I cache the object
Redis::set('pay-period-instance', json_encode($this));
return $this;
}
}
So when I instantiate this class, with $ppsvc = new PayPeriodService; in another class, the $instance variable in the PayPeriodService file is valid and fully reconsituted, fully functional. But the returned instance in $ppsvc is a mindless zombie shell of what it ought to be: no instance data, no methods.
What is the magic I need to invoke to get the restored object to travel abroad as it needs must do? I have explored the Serializable interface, and tried with un/serialize in place of the json_encode/decode with no significant change to my problem.
The problem is that __construct() method does NOT return anything. What you want is a singleton (AFAICU).
Look at this example:
class A {}
class B {
public function __construct(){return new A;}
}
$b = new B;
print_r($b); // B
So has you see even having the constructor returning a different class, that is not going to happen. There are several ways to accomplish this, so you can take a look on the web.
A simple example:
class PayPeriodService {
/**
* #var self
*/
static private $instance;
// private removes the possibility to make a new instance
private function __construct()
{
// object construction logic here
}
/**
* #return PayPeriodService
*/
static public function getInstance()
{
if(!self::$instance)
{
self::$instance = new static;
}
return self::$instance;
}
}
$ppsv = PayPeriodService::getInstance(); // will return what you intend
Unless the object is constantly mutating on Redis, this will do the trick. But you can easily adapt if needed

Derived Classes in Php Phalcon

I am fairly new to php phalcon and the language itself. I am making a website that involves an abstract class and derived classes.
The Abstract Class:
<?php
abstract class UsersAbstract extends \Phalcon\Mvc\Model {
private $Full_Name; //
private $Mobile_Number; //
private $Email_ID; //
private $City; //
private $Country; //
private $DoB; //
private $Gender; //
private $Age; //
private $Availability_Flag; /*value of flag is 1 for active and 0 for inactive*/
/********setters and getters for all data members which I have not written here*******/
public function getSource()
{
return 'users_abstract';
}
}
The derived class
<?php
class UserPatients extends UsersAbstract
{
private $Patient_ID;
private $Guardian_Name;
private $Doctors = array();
public function getSource()
{
return 'user_patients';
}
/***************setter and getter for patient id*******************/
public function getPatientID()
{
return $this->Patient_ID;
}
public function setPatientID($value)
{
$this->Patient_ID = $value;
}
/****************setter and getter for guardian name******************/
public function getGuardianName()
{
return $this->Guardian_Name;
}
public function setGuardianName($value)
{
$this->Guardian_Name = $value;
}
/****************getter and setter for doctor array*********************/
public function getDoctors()
{
return $this->Doctors;
}
public function setDoctors($value)
{
$this->Doctors = $value;
}}
In my controller, I am reading data from a form in a view. An object of the class UserPatients is declared and its data members are set. Here is the action method that I am calling in the controller PatientSignInController:
public function SaveAction()
{
if (!empty($_POST)){
$patient_data = new UserPatients();
$patient_data->setFull_Name($_POST['Full_Name']);
$patient_data->setGuardianName($_POST['Guardian_Name']);
$patient_data->setDoB($_POST['DoB']);
$patient_data->setAge($_POST['Age']);
$patient_data->setGender($_POST['gender']);
$patient_data->setMobile_Number($_POST['Contact_No']);
$patient_data->setEmail_Address($_POST['Email_ID']);
$patient_data->setCity($_POST['City']);
$patient_data->setCountry($_POST['Country']);
$patient_data->setPatientID($_POST['Patients_ID']);
$patient_data->setFlag(1);
$doctorsArray = array("ACD","ABC"); //some hard coded values for the time being
$patient_data->setDoctors($doctorsArray);
$patient_medical_info = new PatientInfo();
$patient_medical_info->setBP($_POST['BP']);
$patient_medical_info->setTemperature($_POST['Temperature']);
$patient_medical_info->setInformation($_POST['Info']);
$patient_medical_info->setPatientID($_POST['Patients_ID']);
$patient_medical_info->setDateOfMeeting(date("d/m/y"));
$patient_data->save();
$patient_medical_info->save();
$this->response->redirect("../../../../WebMCare/PatientSignIn/Index");
}
}
The structure of my database is the same as these classes - I have a table Users_Abstract with all the attributes of the abstract class and I have a table User_Patients with all the attributes of the child class.
When I hit the save button on the form in the view and check the database tables, I discover that the new entries are added in the patient_info table. Which means that the $patient_medical_info->save() is working.
However, the table users_abstract does not contain any new data for the corresponding object, while the table user_patients does get the associated data. I checked messages for errors in save method, but it returned nothing.
I can't seem to find anything online.
Please help me.
I have tried storing data in a single table by associating one table, with all 12 attributes, to the classes UsersAbstract and User_Patients. Even that does not work.

Design pattern where child classes have mandatory methods with arbitrary parameters

I often come across problems that seem reasonable to be solved in this way - I'll give a concrete fictional example, but I'd like to know the name, best practices - and whether this pattern is a good idea in general.
Problem
I need to notify subscribed users of arbitrary events. Lets say one of the process evaluates "orders" and users subscribe to that event but to only one type of orders.
Usage of solution
I imagine the code should look something along the lines of this:
<?php
// ...
public function processOrders() {
// ...
(new notifications\orders())->send( $typeOfOrderThatWasJustProcessed );
// ...
}
Implementation
So I create the base notification class:
<?php
abstract class notifications {
abstract public function configurationForm();
abstract public function send();
}
and the child class for this particular use case (syntax is invalid, abstract method signature differs from base class, bear with me):
namespace notifications;
class orders extends \notifications {
public function configurationForm() {
// prepare and return a form that will be rendered to HTML
// where the user chooses type of order that he is interested in
}
abstract public function send($type) {
// fetches needed users using the configuration which
// was provided via the form above
}
}
So each type of notification will have to have arbitrary parameters. They inform the notification object about entities that were processed - so that the notification code can decide itself who to send the emails to.
Treat the $type in this example as a dynamic value - any number of types can be added via database.
As previously stated, this is not even possible with abstract classes in PHP, which way should I look?
I would add the parameters needed via the constructor of the concrete notifications classes, then send does not need to receive any....Kind of like a command object inside an observer scenario...
Of course it depends on if the actual values of the parameters are known at instantiation time... if not maybe some kind of parameter object could be passed into the constructor, such that when the parameters change, the parameter object is updated too (as it is a reference in PHP 5)?
namespace notifications;
class orders extends \notifications {
protected $type;
public function __construct($type) {
$this->type = $type;
}
public function configurationForm() {
//...
}
abstract public function send() {
// do stuff with $this->type
}
}
OR
namespace notifications;
class orders extends \notifications {
protected $parameters;
public function __construct(NotificationParameters $parameters) {
//$parameters might be a subclass of NotificationParameters, like OrderNotificationParameters
$this->parameters = $parameters;
}
public function configurationForm() {
//...
}
abstract public function send() {
// do stuff with $this->parameters->getType(); the value of which might have changed since construction time
}
}
What do you reckon?
UPDATE - using sub classes
Command pattern I believe - http://www.sitepoint.com/understanding-the-command-design-pattern/
namespace notifications;
abstract class orders extends \notifications {
abstract public function send() {
// do stuff with $this->type
}
}
class TypeAOrders extends orders {
public function send() {
// do Type A stuff
}
}
class TypeBOrders extends orders {
public function send() {
// do Type B stuff
}
}
....
public function processOrders() {
// ...
$commandBuilder->getNotification(typeOfOrderThatWasJustProcessed)->send();
//$commandBuilder knows which object to build depending on the type and pass any relevant parameters into the constructor...
// ...
}

Common parent classes

I have some variables and functions which need to be available for different classes. Hence, I put all definitions (Variables / functions) to some class:
class common_functions() {
function __construct() {
$this->define_variables();
$this->connect_to_database();
echo "EXEC";
}
function define_variables() {
$this->var1 = "foo";
$this->var2 = "bar";
}
function connect_to_database() {
mysql_connect(...)
}
function do_something() {
//...
}
}
which is the parent of all the others:
class orders extends common_functions {
private $order_item;
function __construct() {
parent::__construct()
$order_item = new item();
}
function show_something() {
echo $order_item->get_something()*$this->var1;
}
}
class item extends common_functions {
pivate $some_number;
function __construct() {
parent::__construct()
$this->number = 123;
}
function get_something() {
return $this->var2*$this->var1*$this->number;
}
}
class some_other_class extends common_functions {
function __construct() {
parent::__construct()
}
// ..
}
However, as executing
$o = new order();
$o->show_something();
the output is
EXEC
EXEC
since the common_functions class is called twice. Especially also mysql-connection is established several times which is quite unefficient.
What I need is some technique so that all the functions and variables (and database-connections) from common_functions are available to all classes without the drawback that e.g. connect_to_database() is executed several times. Some ideas?
If I were you I'd redesign my implementation. Why? Well because it seems to me that neither some_other_class nor item is a common_functions. However they both have common_functions. Thus I'd create only one instance of that class and pass it into the constructor.
Something like this:
class Item {
private $common_functions;
public function __construct($common_functions) {
$this->common_functions = $common_functions;
}
}
class Order {
private $common_functions;
public function __construct($common_functions) {
$this->common_functions = $common_functions;
}
}
What happens now is that both the item and some_other_class objects has a dependency which we inject to common_functions. This obviously means that you have to pass some values to the methods in common_functions but that is a very small price to pay considering what you gain from not inheriting common_functions, like only one db-connection.
Inheritance is cool but in practice it isn't used all that much. It's often much better compose objects than to inherit a bunch of stuff. When designing OO-classes always consider wether an objects relation is an is a or has a relation.
So what you could do using the above example of the orders constructor is the following:
class orders {
private $common_functions;
public function __construct($common_functions) {
$this->common_functions = $common_functions;
$order_item = new Item($common_functions);
}
}
That way both item and order will share the same common_functions object.
Assign a static null variable initially in parent class and check if its null or not.
class common_functions {
private static $dbInstance = null;
function __construct() {
if(self::$dbInstance == null) {
self::$dbInstance = $this->connect_to_database();
}
}
...
return the the database connection handler or any other than the null value in $this->connect_to_database();

Categories