How to implement Custom channel notifications in Laravel - php

I'm trying to write my custom laravel channel notifications, like this: https://laravel.com/docs/5.7/notifications#custom-channels.
I wrote this code:
AimonChannel.php
class AimonChannel{
public function send($notifiable, Notification $notification)
{
$message = $notification->toAimon($notifiable);
if (is_string($message)) {
$message = new AimonMessage($message);
}
//some code to send sms with curl
}
AimonMessage.php
class AimonMessage
{
public $messaggio = "";
public function messaggio($messaggio){
$this->messaggio = $messaggio;
}
}
SendAimonMessage.php
class SendAimonMessage extends Notification
{
use Queueable;
protected $messaggio;
public function __construct($messaggio)
{
$this->messaggio = $messaggio;
}
public function via($notifiable)
{
return [AimonChannel::class];
}
public function toAimon($notifiable)
{
return (new AimonMessage())
->messaggio($this->messaggio);
}
}
So, the code:
$user->notify(new SendAimonMessage('my custom message'));
is sent, but without the text.
The problem is in the send() function of AimonChannel; the $message variable is always null.
Where is my code mistake?
Thanks!

add return statement in the messaggio function like this:
class AimonMessage {
public $messaggio = "";
public function messaggio($messaggio){
$this->messaggio = $messagio;
return $this;
}
}

Related

Instantiate Class from method return and pass data to constructor PHP

I have notification classes called ProductNotification, OrderNotification, etc, these have a mail method which returns another class which holds further data for the sending of emails:
class ProductNotification {
public function mail()
{
return ProductMail::class;
}
}
class OrderNotification {
public function mail()
{
return OrderMail::class;
}
}
Is there a way to instantiate the ProductMail class from the method, the following doesn't work and I'm not sure how to pass through another variable $data to the constructo.?
class BaseNotification {
public function toMail()
{
return (new $this->mail())->to($email)->send();
{
}
I know that if mail() was a property on the class instead, that this would be possible and I can pass through $data to the constructor as the following works, but is this possible from a method?
class ProductNotification {
public $mail = ProductMail::class;
}
class BaseNotification {
public function toMail()
{
return (new $this->mail($data))->to($email)->send();
{
}
You can store the class as a local variable in the toMail method and then instantiate it.
class BaseNotification {
public function toMail($data)
{
$mail_class = $this->mail();
return new $mail_class($data);
}
}
You can't instantiate an object from a method call, but you can do so from a variable. So just assign the method's return call to a variable:
class ProductNotification extends BaseNotification {
public function mail() {
return ProductMail::class;
}
}
class OrderNotification extends BaseNotification {
public function mail() {
return OrderMail::class;
}
}
class BaseNotification {
public function toMail()
{
$data = [];
$class = $this->mail();
return (new $class($data))->to($email)->send();
{
}
Though it might be cleaner to just use the mail() method to build the mail:
class ProductNotification extends BaseNotification {
public function mail($data) {
return new ProductMail($data);
}
}
class OrderNotification extends BaseNotification {
public function mail($data) {
return new OrderMail($data);
}
}
class BaseNotification {
public function mail() {
throw new \Exception("not implemented");
}
public function toMail()
{
$data = [];
return $this->mail($data)->to($email)->send();
{
}

How to access method without create object in laravel

How to create system like System()->parameter()->parmKey or like
it's return value 123
parmKey not fixed it's a change or dynamically
I am not sure, how can implement this system in laravel
this is feature in php oop named Chaining methods
example :
<?php
class Message
{
public $message;
function __construct()
{
$this->message = "";
}
public function newLine($line)
{
$this->message .= $line;
return $this;
}
public function getMessage()
{
return $this->message;
}
}
$message = new Message();
echo $message->newLine('Hello')->newLine('My name is yazan')->getMessage();

PHP OOP: Create global array of messages

I am trying to display an array of messages at the end of my PHP class. My message handler is working, but only if I "add_message" from within the main parent class and not if I call this function from within a child class. Sorry if this is vague but was not sure how to word the question.
TLDR; How can I add a message from within class Example?
MAIN PARENT CLASS
class Init {
public function __construct() {
$this->load_dependencies();
$this->add_messages();
$this->add_msg_from_instance();
}
private function load_dependencies() {
require_once ROOT . 'classes/class-messages.php';
require_once ROOT . 'classes/class-example.php';
}
public function add_messages() {
$this->messages = new Message_Handler();
$this->messages->add_message( 'hello world' );
}
// I Would like to add a message from within this instance....
public function add_msg_from_instance() {
$example = new Example();
$example->fire_instance();
}
public function run() {
$this->messages->display_messages();
}
}
MESSAGE HANDLER
class Message_Handler {
public function __construct() {
$this->messages = array();
}
public function add_message( $msg ) {
$this->messages = $this->add( $this->messages, $msg );
}
private function add( $messages, $msg ) {
$messages[] = $msg;
return $messages;
}
// Final Function - Should display array of all messages
public function display_messages() {
var_dump( $this->messages );
}
}
EXAMPLE CLASS
class Example {
public function fire_instance() {
$this->messages = new Message_Handler();
$this->messages->add_message( 'Hello Universe!' ); // This message is NOT being displayed...
}
}
Because you want to keep the messages around different object, you should pass the object or use a static variable.
I would use a static variable like so:
class Init {
public function __construct() {
$this->load_dependencies();
$this->add_messages();
$this->add_msg_from_instance();
}
private function load_dependencies() {
require_once ROOT . 'classes/class-messages.php';
require_once ROOT . 'classes/class-example.php';
}
public function add_messages() {
// renamed the message handler variable for clarity
$this->message_handler = new Message_Handler();
$this->message_handler->add_message( 'hello world' );
}
// I Would like to add a message from within this instance....
public function add_msg_from_instance() {
$example = new Example();
$example->fire_instance();
}
public function run() {
$this->message_handler->display_messages();
}
}
class Message_Handler {
// use a static var to remember the messages over all objects
public static $_messages = array();
// add message to static
public function add_message( $msg ) {
self::$_messages[] = $msg;
}
// Final Function - Should display array of all messages
public function display_messages() {
var_dump( self::$_messages );
}
}
class Example {
public function fire_instance() {
// new object, same static array
$message_handler = new Message_Handler();
$message_handler->add_message( 'Hello Universe!' );
}
}
// testing...
new Init();
new Init();
$init = new Init();
$init->add_msg_from_instance();
$init->add_msg_from_instance();
$init->add_msg_from_instance();
$init->run();
Although global variables might not be the best design decision, you have at least two approaches to achieve what you want:
Use singleton.
Nowadays it is considered anti-pattern, but it is the simplest way: make message handler a singleton:
class MessageHandler
{
private static $instance;
private $messages = [];
public static function instance(): self
{
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct()
{
}
public function addMessage($message): self
{
$this->messages[] = $message;
return $this;
}
public function messages(): array
{
return $this->messages;
}
}
Then instead of creating a new instance of MessageHandler access it via the static method MessageHandler::instance(). Here is a demo.
Use DI container to inject the same instance (that is created once and held in the container) into all instances that need to access it. This approach is more preferable, but harder to implement in the project where there is no DI container available in the first place.

PHP : How to call method from other class without inheritance

I have a little problem here, sorry if asking a dumb question.
so, I have StoreCategories Class which have :
class StoreCategories
{
private $store_category_id;
private $category;
public function setStoreCategoryId($store_category_id)
{
$this->store_category_id = $store_category_id;
}
public function getStoreCategoryId()
{
return $this->store_category_id;
}
public function setCategory($category)
{
$this->category = $category;
}
public function getCategory()
{
return $this->category;
}
}
In my index.php I declare the object like this :
$types = array();
while($stmt->fetch())
{
$type = new StoreCategories();
$type->setCardId($card_id);
$type->setStoreCategoryId($store_category_id);
$type->setCategory($category);
array_push($types, $type);
}
As you see, I want to set Card ID which is not in the StoreCategories Class..
I have a Card Class like this :
class Card
{
private $card_id;
public function setCardId($card_id)
{
$this->card_id = $card_id;
}
public function getCardId()
{
return $this->card_id;
}
}
I know I can user Class Card extends StoreCategories to get the Card ID, but it's too much risk..
Anyone have the other ways to do it ?
Thanks :)
You can use Traits
Move common part of the code into new trait:
trait CardIdTrait {
private $card_id;
public function setCardId($card_id)
{
$this->card_id = $card_id;
}
public function getCardId()
{
return $this->card_id;
}
}
And modify Card class to:
class Card {
use CardIdTrait;
}
and
class StoreCategories
{
use CardIdTrait;
private $store_category_id;
private $category;
// ...
}

How to user ThrowException matcher in PHPSpec?

I have problem in using ExceptionMatcher...My example spec:
class DescribeBall extends \PHPSpec\Context {
private $_ball = null;
function before() {
$this->_ball = $this->spec(new Ball);
}
function itShouldHaveStatusRolledOnRoll() {
$this->_ball->roll();
$this->_ball->getStatus()->should->be('Rolled');
}
function itShouldThrowException() {
$this->_ball->getException()->should->throwException('Exception','Error');
}
}
My example class
class Ball {
private $status = null;
public function roll() {
$this->status = 'Rolled';
}
public function getStatus() {
return $this->status;
}
public function getException() {
throw new Exception('Error');
}
}
Anyone used this matcher with success?
$this->_ball->getException()->should->throwException('Exception','Error');
Thanks to my colleagues:
"The last time I looked at it, it used closures (unless Marcello changed it meanwhile) it should still work like this":
function itShouldThrowException() {
$ball = $this->_ball;
$this->spec(function() use ($ball) {
$ball->getException();
})->should->throwException('Exception','Error');
}

Categories