Overriding a vendor file in Laravel Framework 7.29.3 - php

I'm trying to override a vendor file located at "vendor\cimpleo\omnipay-authorizenetrecurring\src\Objects\Schedule.php" to correct some issues.
composer.json
"autoload": {
"psr-4": {
"App\\": "app/",
"Cimpleo\\": "app/Overrides/"
},
"classmap": [
"database/seeds",
"database/factories",
"vendor/google/apiclient/src",
"vendor/google/apiclient-services/src/Google"
],
"exclude-from-classmap": ["vendor\\cimpleo\\omnipay-authorizenetrecurring\\src\\Objects\\Schedule.php"]
}
Then I copied and edited the Schedule.php to folder "app\Overrides".
namespace Cimpleo;
use Academe\AuthorizeNet\PaymentInterface;
use Academe\AuthorizeNet\AbstractModel;
use Omnipay\Common\Exception\InvalidRequestException;
use DateTime;
class Schedule extends AbstractModel
{
...
The vendor Schedule.php file looks like this.
namespace Omnipay\AuthorizeNetRecurring\Objects;
use Academe\AuthorizeNet\PaymentInterface;
use Academe\AuthorizeNet\AbstractModel;
use Omnipay\Common\Exception\InvalidRequestException;
use DateTime;
class Schedule extends AbstractModel
{
const SCHEDULE_UNIT_DAYS = 'days';
const SCHEDULE_UNIT_MONTHS = 'months';
protected $intervalLength;
protected $intervalUnit;
protected $startDate;
protected $totalOccurrences;
protected $trialOccurrences;
public function __construct($parameters = null) {
parent::__construct();
$this->setIntervalLength($parameters['intervalLength']);
$this->setIntervalUnit($parameters['intervalUnit']);
$this->setStartDate($parameters['startDate']);
$this->setTotalOccurrences($parameters['totalOccurrences']);
if (isset($parameters['trialOccurrences'])) {
$this->setTrialOccurrences($parameters['trialOccurrences']);
}
}
public function jsonSerialize() {
$data = [];
if ($this->hasIntervalLength()) {
$data['interval']['length'] = $this->getIntervalLength();
}
if ($this->hasIntervalUnit()) {
$data['interval']['unit'] = $this->getIntervalUnit();
}
if ($this->hasStartDate()) {
$data['startDate'] = $this->getStartDate();
}
if ($this->hasTotalOccurrences()) {
$data['totalOccurrences'] = $this->getTotalOccurrences();
}
if ($this->hasTrialOccurrences()) {
$data['trialOccurrences'] = $this->getTrialOccurrences();
}
return $data;
}
protected function setIntervalLength(int $value) {
if ($value < 7 || $value > 365) {
throw new InvalidRequestException('Interval Length must be a string, between "7" and "365".');
}
$this->intervalLength = (string)$value;
}
...
The class is instantiated here
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Omnipay\Omnipay;
use Omnipay\AuthorizeNetRecurring;
use Omnipay\AuthorizeNetRecurring\Objects\Schedule;
use Omnipay\Common\CreditCard;
class AuthorizeNetRecurringController extends Controller
{
private $gateway;
public function __construct() {
$this->gateway = Omnipay::create('AuthorizeNetRecurring_Recurring');
$this->gateway->setAuthName('3KJZb44jR');
$this->gateway->setTransactionKey('2fFqRA7w22a2G7He');
$this->gateway->setTestMode(true);
}
//
public function createSubscription(Request $request) {
$schedule = new Schedule([
//For a unit of days, use an integer between 7 and 365, inclusive. For a unit of months, use an integer between 1 and 12, inclusive.
'intervalLength' => '1',
// use values 'days' or 'months'
'intervalUnit' => 'months',
//date in format 'YYYY-mm-dd'
'startDate' => date("Y-m-d"), //'2020-03-10',
//To create an ongoing subscription without an end date, set totalOccurrences to "9999".
'totalOccurrences' => '12',
//If a trial period is specified, include the number of payments during the trial period in totalOccurrences.
'trialOccurrences' => '1',
]);
...
Then run composer dump-autoload. After running the script the app is still calling the vendor file that causes the error below. Composer changes doesn't seem to work.
Omnipay\Common\Exception\InvalidRequestException
Interval Length must be a string, between "7" and "365".
Omnipay\AuthorizeNetRecurring\Objects\Schedule::setIntervalLength
D:\xampp\htdocs\SBF_app_version1.5\vendor\cimpleo\omnipay-authorizenetrecurring\src\Objects\Schedule.php:56
Thanks

I think you have to import the overridden class, instead of the original one.
use Cimpleo\Schedule;
// use Omnipay\AuthorizeNetRecurring\Objects\Schedule;
But a better solution to this problem would be to use inheritance:
namespace App\Overrides\Cimpleo;
use Omnipay\AuthorizeNetRecurring\Objects\Schedule as BaseSchedule;
class Schedule extends BaseSchedule
{
...
}
And then in the controller you would import the new Schedule class:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Omnipay\Omnipay;
use Omnipay\AuthorizeNetRecurring;
use App\Overrides\Cimpleo\Schedule;
use Omnipay\Common\CreditCard;
class AuthorizeNetRecurringController extends Controller
{
...
}
Also you would have to remove the new autoloading instruction and also exclude-from-classmap in composer. Just autoload app directory and it would be enough:
"autoload": {
"psr-4": {
"App\\": "app/"
},

Related

Attempted to call function "yaml_parse_file" from the global namespace

I am new to Symfony, Facing problem while trying to run the cron job. I am really clueless, whats wrong here. It seems that I am trying to access some functions present in app/config/functions.php from the global namespace, But I can't figure out which namespace is it. Following is my code.
<?php
namespace App\Command;
use App\Services\Upcontent\Upcontent;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpcontentRefreshCommand extends Command
{
protected static $defaultName = 'app:upcontent-refresh';
private $upcontent;
public function __construct(Upcontent $upcontent)
{
$this->upcontent = $upcontent;
parent::__construct();
}
protected function configure()
{
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln([
'',
'=================',
'Upcontent Refresh',
'=================',
'',
]);
$output->writeln('Clearing Cache...');
clear_cache();
$output->writeln('Cache Cleared');
$output->writeln('Refreshing Sports Topic...');
$output->writeln('Loading, be patient...');
$sports = $this->upcontent->getTopic('########');
$output->writeln([
'',
'=====================',
'End Upcontent Refresh',
'=====================',
'',
]);
}
}
?>
The error occur when I run, php72 bin/console app:upcontent-refresh Please help. Thanks in advance.
You will probably have to update the "autoload"-section to make sure that your custom functions.php is loaded.
{
"autoload": {
"psr-4" {
"App\\": "src/"
},
"files": ["app/config/functions.php"]
}
}
You might also want to refactor that file to instead move the functions into some kind of service-class, e.g. like this:
# src/Yaml/Parser.php
<?php
namespace App\Yaml;
class Parser
{
public function parseFile(string $fileName)
{
// The logic from your yaml_parse_file() inside your functions.php
}
}
Then in your command (or wherever you need your custom yaml parsing) inject the service:
use App\Yaml\Parser;
class MyService
{
private $yamlParser;
public function __construct(Parser $yamlParser)
{
$this->yamlParser = $yamlParser;
}
// ...
public function something()
{
$this->yamlParser->parseFile($filename);
}
}
Since Symfony provides a Yaml-component, you might even want to use that instead.

Add custom Services - Symfony ; Sylius

I don't understand Why I can't create custom services. I get errors with the both technic. I don't find anything about that in your doc.
# app/config/services.yml
services:
jdf.utils.phphelper:
class: JDF\Utils\PhpHelper
// src/JDF/Utils/PhpHelper.php
namespace JDF\Utils;
class PhpHelper
{
/**
* [pdebug description]
* #param string $var The string to beautiful show
* #param string $msg Description of the $var
* #param integer $displayNone
* #return echo pre print_r $var string
*/
public function pdebug ($var, $msg = '', $displayNone = 0) {
}
}
Case 1 : (Pass PhpHelper in the __construct function)
// src/JDF/CsvTreatmentBundle\Controller/ImportController
namespace JDF\CsvTreatmentBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use JDF\Utils\PhpHelper;
use Psr\Log\LoggerInterface;
/**
*
*/
class ImportController extends Controller {
function __construct(
PhpHelper $PhpHelper
) {
}
public function indexAction() {
//$test = $this->container->get('jdf.utils.phphelper');
return new Response('<hr>');
}
} /*End of class*/
Error 1 :
Catchable Fatal Error: Argument 1 passed to JDF\CsvTreatmentBundle\Controller\ImportController::__construct() must be an instance of JDF\Utils\PhpHelper, none given, called in C:\kitutilitaire\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Controller\ControllerResolver.php on line 202 and defined
500 Internal Server Error - ContextErrorException
Case 2 (just use get() controller method) :
// src/JDF/CsvTreatmentBundle\Controller/ImportController
namespace JDF\CsvTreatmentBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use JDF\Utils\PhpHelper;
use Psr\Log\LoggerInterface;
/**
*
*/
class ImportController extends Controller {
function __construct(
//PhpHelper $PhpHelper
// LoggerInterface $logger
) {
}
public function indexAction() {
$test = $this->container->get('jdf.utils.phphelper');
// $logger = $this->container->get('logger');
return new Response('<hr>');
}
} /*End of class*/
Error 2 :
Attempted to load class "PhpHelper" from namespace "JDF\Utils".
Did you forget a "use" statement for another namespace?
Stack Trace
in var\cache\dev\appDevDebugProjectContainer.php at line 3555 -
*/
protected function getJdf_Utils_PhphelperService()
{
return $this->services['jdf.utils.phphelper'] = new \JDF\Utils\PhpHelper();
}
/**
EDIT : composer.json autoload
"autoload": {
"psr-4": {
"AppBundle\\": "src/AppBundle/",
"JDF\\CsvTreatmentBundle\\": "src/JDF/CsvTreatmentBundle/",
"JDF\\Utils\\": "src/JDF/Utils/PhpHelper"
},
"classmap": ["app/AppKernel.php", "app/AppCache.php"]
},
Thank in advence for your help.
Controllers do not get any injection by default. They have $this->container always available to get to all your services.
So nothing more to do than:
class ImportController extends Controller {
public function indexAction() {
$test = $this->container->get('jdf.utils.phphelper');
// $logger = $this->container->get('logger');
return new Response('<hr>');
}
}
FYI: The cache file appDevDebugProjectContainer is auto generated and of no significance to your problem.
I've solved the problem with change my composer.json.
For can use $this->container->get('jdf.utils.phphelper'); the all good code is :
# app/config/services.yml
services:
jdf.utils.phphelper:
class: JDF\Utils\PhpHelper
// src/JDF/Utils/PhpHelper.php
namespace JDF\Utils;
class PhpHelper {}
// src/JDF/CsvTreatmentBundle\Controller/ImportController
namespace JDF\CsvTreatmentBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use JDF\Utils\PhpHelper;
/**
*
*/
class ImportController extends Controller {
public function indexAction() {
$test = $this->container->get('jdf.utils.phphelper');
return new Response('<hr>');
}
} /*End of class*/
AND IMPORTANT : The composer.json :
"autoload": {
"psr-4": {
"JDF\\CsvTreatmentBundle\\": "src/JDF/CsvTreatmentBundle/",
"JDF\\Utils\\": "src/JDF/Utils/"
},
"classmap": ["app/AppKernel.php", "app/AppCache.php"]
},
And the CLI command : php composer.phar dump-autoload
Thank to colburton for this time and interest at my issue.

Php autoloading not working in symfony dispatcher example

I am trying to just check out the symfony event dispatcher class and i have been following this online tutorial , so i have the following in my index.php file:
<?php
require('vendor/autoload.php');
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher;
$dispatcher->addListener('UserSignedUp' , function(Event $event){
// die('Handling It !!');
var_dump($event);
});
$event = new App\Events\UserSignedUp( (object) [ 'name' => 'gautam' , 'email' => 'gautamz07#yahoo.com' ] );
$dispatcher->dispatch('UserSignedUp' , $event);
and i have the following directory structure:
event_dis
- app
- events
- UserSignUp.php
- vendor
- index.php
- composer.json
I have the following in my composer.json file:
{
"require": {
"symfony/event-dispatcher": "^3.2"
},
"autoload" : {
"psr-4" : {
"App\\" : "app/"
}
}
}
The UserSignedUp.php class looks like the following :
<?php
namespace App\Events;
class UserSignedUp extends Event {
public $user;
public function __construct($user) {
$this->user = $user;
}
}
Now since i have the following line in my index.php file:
$event = new App\Events\UserSignedUp( (object) [ 'name' => 'gautam' , 'email' => 'gautamz07#yahoo.com' ] );
The UserSignedUp class gets called and i get the following error in my browser:
Class 'App\Events\Event' not found in C:\xampp\htdocs\symfony_compo\event_dis\app\Events\UserSignedUp.php on line 6
Now why am i getting this error , in the tutorial this same example works perfectly, but on my local machine this does't , can somebody tell me what am i doing wrong here ??
Event class does not exists in App\Events namespace. You should edit UserSignedUp.php and add use Symfony\Component\EventDispatcher\Event;:
<?php
namespace App\Events;
use Symfony\Component\EventDispatcher\Event;
class UserSignedUp extends Event {
public $user;
public function __construct($user) {
$this->user = $user;
}
}

How to call view from an other file than controller

I am creating a laravel 5.2 package, following are my files:
packages/
-Shreeji/
--Ring/
---composer.json
---src/
----Ring.php
----RingModel.php
----RingServiceProvider
----Views/
-----ringslist.blade.php
composer.json
{
"name": "shreeji/ring",
"description": "Simple",
"license": "MIT",
"authors": [
{
"name": "author",
"email": "email#gmail.com"
}
],
"autoload": {
"psr-4": {
"Shreeji\\Ring\\": "src/"
}
},
"minimum-stability": "dev",
"require": {
"Illuminate/support": "~5"
}
}
Ring.php
namespace Shreeji\Ring;
use Illuminate\Http\Response;
Class Ring {
function __construct() {
}
public function get_all()
{
return view("ring::ringlist");
}
}
RingServiceProvider.php
namespace Shreeji\Ring;
use Illuminate\Support\ServiceProvider;
Class RingServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('ring', function($app){
return new Ring;
});
}
public function boot()
{
$this->loadViewsFrom(__DIR__ . '/Views', 'ring');
}
}
ringlist.blade.php
<!DOCTYPE html>
<html>
<body>
<h1>Welcome</h1>
</body>
</html>
And in app/Http/Controllers I have created a test file like this:
Ringcontroller.php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Shreeji\Ring\Ring;
class RingController extends Controller
{
public function index()
{
$ring = New Ring();
$ring->get_all();
}
}
When I call the controller, browser keeps loading and crashed systematically. I don't know if I can use view outside any controller class like such.
Let me know if I did any mistake in calling view from Ring.php file.
Couple issues I see:
You want to use views, but your package does not require the illuminate/view package. You need to update your composer.json file to require "illuminate/view": "~5".
The view() function is a helper method included at Illuminate\Foundation\helpers.php. Unless you want to depend on the entire Laravel framework just for this function, you will need to create your own view() function. The code is below, where you put it is up to you.
if (! function_exists('view')) {
/**
* Get the evaluated view contents for the given view.
*
* #param string $view
* #param array $data
* #param array $mergeData
* #return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
function view($view = null, $data = [], $mergeData = [])
{
$factory = app(ViewFactory::class);
if (func_num_args() === 0) {
return $factory;
}
return $factory->make($view, $data, $mergeData);
}
}
Once you get the view stuff working, you can make views all day long, but if you don't return anything from your controller, you're not going to see anything. Make sure you return something from your controller methods.
You can use somethin like view composer Docs
In your RingServiceProvider register a composer
use Illuminate\Contracts\View\Factory as ViewFactory;
public function boot(ViewFactory $view)
{
$view->composer('*', 'App\Http\ViewComposers\SomeComposer');
}
And in App\Http\ViewComposers\SomeComposer
use Illuminate\Contracts\View\View;
public function compose(View $view)
{
$view->with('count', '1');
}
Play around with it, basically I am using it share $variables on particular views but maybe this can help you achieve what you want.
Or u can just use Illuminate\Contracts\View\View; to load your view that you need!

Using parseincludes in Laravel5 Fractal

Struggling using parseIncludes in https://github.com/thephpleague/fractal.
I have two tables, Property and Weeks. Each property has many weeks. Using Fractal I can return my property item with a collection of weeks. What I want to do is use parseIncludes, so that the return of weeks is optional.
PropertyTransformer.php
<?php
namespace App\Transformer;
use App\Models\Property;
use League\Fractal\TransformerAbstract;
class PropertyTransformer extends TransformerAbstract
{
protected $availableIncludes = [
'week'
];
public function transform(Property $property)
{
return [
'id' => (int) $property['PropertyID'],
'PropertyName' => $property['PropertyName'],
'ExactBeds' => (int) $property['ExactBeds'],
'weeks' => $property->week
];
}
/**
* Include Week
*
* #return League\Fractal\ItemResource
*/
public function includeWeek( Property $property )
{
$week = $property->week;
return $this->item($week, new WeekTransformer);
}
}
WeekTransformer.php
<?php
namespace App\Transformer;
use App\Models\Week;
use League\Fractal;
class WeekTransformer extends Fractal\TransformerAbstract
{
public function transform(Week $week)
{
return [
'Week' => $week['week'],
'Available' => $week['available'],
'Price' => (int) $week['price'],
];
}
}
My PropertyController.php
<?php namespace App\Http\Controllers\Api\v1;
use App\Http\Requests;
use App\Models\Week;
use Illuminate\Support\Facades\Response;
use App\Models\Property;
use League\Fractal;
use League\Fractal\Manager;
use League\Fractal\Resource\Collection as Collection;
use League\Fractal\Resource\Item as Item;
use App\Transformer\PropertyTransformer;
class PropertyController extends \App\Http\Controllers\Controller {
public function show($id)
{
$property = Property::with('bedroom')->with('week')->find($id);
$fractal = new Fractal\Manager();
if (isset($_GET['include'])) {
$fractal->parseIncludes($_GET['include']);
}
$resource = new Fractal\Resource\Item($property, new PropertyTransformer);
//$resource = new Fractal\Resource\Collection($properies, new PropertyTransformer);
return $fractal->createData( $resource )->parseIncludes('weeks')->toJson();
}
I get the following error on the parseIncludes:-
Method 'parseIncludes' not found in class \League\Fractal\Scope
I'm following the guide here on transformers - http://fractal.thephpleague.com/transformers/
I think I am going wrong somewhere here where it says:-
These includes will be available but can never be requested unless the Manager::parseIncludes() method is called:
<?php
use League\Fractal;
$fractal = new Fractal\Manager();
if (isset($_GET['include'])) {
$fractal->parseIncludes($_GET['include']);
}
If I remove the parseIncludes, I don't get an error, I also get my property data with my collection of weeks, but ?include=week doesn't work to optionally get it.
Your problem is in this line:
return $fractal->createData( $resource )->parseIncludes('weeks')->toJson();
createData() returns \League\Fractal\Scope and it has no parseInlcudes method.
You've already called parseIncludes here:
if (isset($_GET['include'])) {
$fractal->parseIncludes($_GET['include']);
}
So just remove the second call to it in the return statement:
return $fractal->createData($resource)->toJson();

Categories