PHP Class chaining - php

I am using SMoney package from Picoss, my code :
$http = new HttpClient("token","url");
$api = new SMoneyApi($http);
$profile = new \Picoss\SMoney\Entity\Profile();
$profile->setCivility(0);
$profile->setLastName("Doe");
$profile->setFirstName("John");
$profile->setEmail("johndoe#gmail.com");
$profile->setPhoneNumber("000000000");
$user = new \Picoss\SMoney\Entity\User();
$user->setAppUserId(time());
$user->setProfile($profile);
$user->setType(1);
$api->user()->save($user); // works
How can I use on my element this code for get all errors:
$api->user()->getErrors(); // works
I would like make :
$api->user()->save($user)->getErrors(); // doesn't works
But i can't, have you solutions ?
Informations :
SMoneyApi have method user() which extends ApiUser
APIUser extends ApiBase
ApiBase (abstract class) have method :
getErrors();
getErrors extends SMoneyError
https://github.com/picoss/SMoney/blob/master/src/SMoneyError.php
==
Solved :
$d = $api->user();
$apis = $d->save($user);
var_dump($d->getErrors());
Thanks

Related

Attempted to call an undefined method named "getChoices" of class "Symfony\Component\Form\ChoiceList\View\ChoiceListView"

In the app updated from Symfony 2.3 to 2.8, we have changed the choice list that changed in 2.7.
See the links below for documentation on previous code and changes.
I got the following error in it.
Does this mean I have to create getChoices in StaffChoiceLoader?
I think only loadChoiceList, loadChoicesForValues, loadValuesForChoices required for ChoieLoaderInterface is needed.
Beforecode
Symfony: Unable to reverse value for property path [...]: The choice [...] does not exist or is not unique
Document
https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.7.md
ChoiceLoader.php
class StaffChoiceLoader implements ChoiceLoaderInterface
{
public function loadChoiceList($value = null)
{
$staffs = $this->staffService->getStaffByShop($this->loginStaff->getShop());
$factory = new DefaultChoiceListFactory();
$choiceList = $factory->createListFromChoices($staffs);
$choiceListView = $factory->createView(
$choiceList,
function ($staffs, $key) use ($staffs) {
return $staffs[$key];
});
return $choiceListView;
}
}

Replace/decorate `translation.reader`

I filled a bug but it seams I'm off :p
I just want to replace the service Symfony\Component\Translation\Reader\TranslationReader (translation.reader) with my own class. In fact I want to know how to replace any service of SF4 if I want
translation.reader::addLoader() is normally called by the framework but if I decorate with my own class addLoader is not called.
Can you tell me how I can just drop replace my own service ?
https://github.com/symfony/symfony/issues/28843
Symfony version(s) affected: 4.1.6
Description
Cannot decorate translation.reader (I want to change the default i18n file loading process)
How to reproduce
copy/adapt Symfony\Component\Translation\Reader\TranslationReader to App\Translation\Reader\TranslationReader
Follow https://symfony.com/doc/current/service_container/service_decoration.html
Modify services.yaml
Symfony\Component\Translation\Reader\TranslationReader: ~
App\Translation\Reader\TranslationReader:
decorates: Symfony\Component\Translation\Reader\TranslationReader
#translation.reader: '#App\Translation\Reader\TranslationReader'
Without the alias : the new service is ignored
With the alias : read() is trigger but not addLoader()
Here are the generated injection file getTranslationReaderService.php :
<?php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the private 'App\Translation\Reader\TranslationReader' shared autowired service.
include_once $this->targetDirs[3].'/vendor/symfony/translation/Reader/TranslationReaderInterface.php';
include_once $this->targetDirs[3].'/src/Translation/Reader/TranslationReader.php';
return $this->privates['App\Translation\Reader\TranslationReader'] = new \App\Translation\Reader\TranslationReader();
By default it looks like :
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the private 'translation.reader' shared service.
include_once $this->targetDirs[3].'/vendor/symfony/translation/Reader/TranslationReaderInterface.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Reader/TranslationReader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/LoaderInterface.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/ArrayLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/FileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/PhpFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/YamlFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/XliffFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/PoFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/MoFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/QtFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/CsvFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/IcuResFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/IcuDatFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/IniFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/JsonFileLoader.php';
$this->privates['translation.reader'] = $instance = new \Symfony\Component\Translation\Reader\TranslationReader();
$a = ($this->privates['translation.loader.yml'] ?? $this->privates['translation.loader.yml'] = new \Symfony\Component\Translation\Loader\YamlFileLoader());
$b = ($this->privates['translation.loader.xliff'] ?? $this->privates['translation.loader.xliff'] = new \Symfony\Component\Translation\Loader\XliffFileLoader());
$instance->addLoader('php', ($this->privates['translation.loader.php'] ?? $this->privates['translation.loader.php'] = new \Symfony\Component\Translation\Loader\PhpFileLoader()));
$instance->addLoader('yaml', $a);
$instance->addLoader('yml', $a);
$instance->addLoader('xlf', $b);
$instance->addLoader('xliff', $b);
$instance->addLoader('po', ($this->privates['translation.loader.po'] ?? $this->privates['translation.loader.po'] = new \Symfony\Component\Translation\Loader\PoFileLoader()));
$instance->addLoader('mo', ($this->privates['translation.loader.mo'] ?? $this->privates['translation.loader.mo'] = new \Symfony\Component\Translation\Loader\MoFileLoader()));
$instance->addLoader('ts', ($this->privates['translation.loader.qt'] ?? $this->privates['translation.loader.qt'] = new \Symfony\Component\Translation\Loader\QtFileLoader()));
$instance->addLoader('csv', ($this->privates['translation.loader.csv'] ?? $this->privates['translation.loader.csv'] = new \Symfony\Component\Translation\Loader\CsvFileLoader()));
$instance->addLoader('res', ($this->privates['translation.loader.res'] ?? $this->privates['translation.loader.res'] = new \Symfony\Component\Translation\Loader\IcuResFileLoader()));
$instance->addLoader('dat', ($this->privates['translation.loader.dat'] ?? $this->privates['translation.loader.dat'] = new \Symfony\Component\Translation\Loader\IcuDatFileLoader()));
$instance->addLoader('ini', ($this->privates['translation.loader.ini'] ?? $this->privates['translation.loader.ini'] = new \Symfony\Component\Translation\Loader\IniFileLoader()));
$instance->addLoader('json', ($this->privates['translation.loader.json'] ?? $this->privates['translation.loader.json'] = new \Symfony\Component\Translation\Loader\JsonFileLoader()));
return $instance;
You can see that loaders are not injected when I do the decorating...
I'm not sure exactly if this is the root of your problem, but here are some remarks. Hopefully this will help you find a solution, even though I'm not actually given a full answer to your question.
1) Some translation services in Symfony are called only during the cache warmup phase. Whenever you change your config, or do a bin/console cache:clear, you'll see these classes are run, and they generate translations in your var/cache/<env>/translations/ folder.
2) You can try to make sure that in your cache, the classe loaded by var/cache/<env>/Container<...>/getTranslation_ReaderService.php is yours and not the default one like this:
$this->privates['translation.reader'] =
new \Symfony\Component\Translation\Reader\TranslationReader();
3) I also encountered a similar issue in the dev environment, where I was trying to replace Symfony\Component\Translation\Translator with my own service, and didn't manage to get my methods to be called at first. Part of the explanation was that when the Symfony Profiler is enabled, Symfony does something like this (in src<env>DebugProjectContainer.php>):
$this->services['translator'] = new \Symfony\Component\Translation\DataCollectorTranslator(
($this->privates['translator.default'] ?? $this->getTranslator_DefaultService())
);
and the DataCollectorTranslator itself is a wrapper for whichever translator it gets as its constructor argument.
I know this is not a perfect answer but hopefully this will help you find your way to a solution.
I've managed to make it work... but please feel free to comment
I had to create a TranslatorPass to add loaders to the decorating service injection file.
<?php
namespace App\Translation\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use App\Translation\Reader\TranslationReader;
class TranslatorPass implements CompilerPassInterface
{
private $readerServiceId;
private $loaderTag;
public function __construct(string $readerServiceId = TranslationReader::class, string $loaderTag = 'translation.loader')
{
$this->readerServiceId = $readerServiceId;
$this->loaderTag = $loaderTag;
}
public function process(ContainerBuilder $container)
{
$loaders = array();
$loaderRefs = array();
foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
$loaderRefs[$id] = new Reference($id);
$loaders[$id][] = $attributes[0]['alias'];
if (isset($attributes[0]['legacy-alias'])) {
$loaders[$id][] = $attributes[0]['legacy-alias'];
}
}
if ($container->hasDefinition($this->readerServiceId)) {
$definition = $container->getDefinition($this->readerServiceId);
foreach ($loaders as $id => $formats) {
foreach ($formats as $format) {
$definition->addMethodCall('addLoader', array($format, $loaderRefs[$id]));
}
}
}
}
}
I've put it in the Kernel.php
protected function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new TranslatorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1000);
}
then
bin/console cache:clear
et voilĂ  !

Using an existing API with codeigniter 2

I dont ask many questions as I like to research for myself but this has me stumped.
I have an existing Codeigniter2(CI) application and am trying to integrate an existing API for a payment system (MangoPay). I have added it as a library and also preloaded it in autoload.php, it is being included with no errors.
My question is about setting up the class structure and addressing the class from my application.
Now, if you were to get this working from a plain old PHP file, the code would look like this (and btw it works on my machine with no issue from a plain php file)
<?php
require_once('../vendor/autoload.php');
$mangoPayApi = new MangoPay\MangoPayApi();
$mangoPayApi->Config->ClientId = 'user_id';
$mangoPayApi->Config->ClientPassword = 'password_here';
$mangoPayApi->Config->TemporaryFolder = 'c:\\wamp\\tmp/';
$User = new MangoPay\UserNatural();
$User->Email = "test_natural#testmangopay.com";
$User->FirstName = "Bob";
$User->LastName = "Briant";
$User->Birthday = 121271;
$User->Nationality = "FR";
$User->CountryOfResidence = "ZA";
$result = $mangoPayApi->Users->Create($User);
var_dump($result);
?>
So, I have created a new class in the libraries folder and if i was to var_dump() the contents of mangoPayApi as below, it throws all kinds of stuff which proves that it is working (ie no PHP errors).
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once('/vendor/autoload.php');
class MangoPayService {
private $mangoPayApi;
private $user;
public function __construct()
{
$this->mangoPayApi = new MangoPay\MangoPayApi();
$this->mangoPayApi->Config->ClientId = 'user_id_here';
$this->mangoPayApi->Config->ClientPassword = 'password_here';
$this->mangoPayApi->Config->TemporaryFolder = 'c:\\wamp\\tmp/';
//var_dump($mangoPayApi);
}
I thought I could just write a method in the class like this
function add_user(){
//CREATE NATURAL USER
$this->user = new user();
$user->Email = 'test_natural#testmangopay.com';
$user->FirstName = "John";
$user->LastName = "Smith";
$user->Birthday = 121271;
$user->Nationality = "FR";
$user->CountryOfResidence = "ZA";
$add_userResult = $this->mangoPayApi->Users->Create($user);
var_dump($add_userResult);
}
and acces it in my application like
<?php echo $this->mangopayservice->add_user() ?>
But i get errors Fatal error: Class 'user' not found in C:\wamp\www\mpapp\application\libraries\MangoPayService.php on line 25 (which is this->user = new user(); this line)
Can anyone explain how to correctly set up this scenario and how to integrate correctly with the API.
if I can get something to create a user simply when a page is opened, I think I can work it from there using the solution as a roadmap.
I will be writing all the integration code once I understand how to make this work.
Thank in advance
MangoPay requires a NaturalUser class. You try to instantiate a user class.
Simply replace your first line of the add_user function with :
$user = new MangoPay\UserNatural();

PHP Instantiate obj class with variable not working

I found a problem that I not sure if is a bug of the php or on my code (probably mine) so let me show you what is happening:
<?php namespace MyApp\Conciliation;
use SimpleExcel\SimpleExcel;
use ForceUTF8\Encoding;
use MyApp\Conciliation\Gol;
class Conciliation {
protected function equalizeFile($file, $providerName)
{
$type = false;
$nfile = 'public'.$file;
// TEST 1: the ideal aproach. not working (see error#1 bellow)
$provider = new $providerName();
// TEST 2: working, getting the correct response
$provider = new Gol();
// TEST 3: working, getting the correct response
$provider = new MyApp\Conciliation\Gol();
$provider->equalize($nfile);
}
Note, the $providerName = 'Gol';
error1
Class 'Gol' not found
http://inft.ly/N8Q6F4B
So, there is any way that I could keeping using variables to instantiate aliases similar as above?
Edit, Problem solved: working example
<?php namespace MyApp\Conciliation;
use SimpleExcel\SimpleExcel;
use ForceUTF8\Encoding;
class Conciliation {
protected function equalizeFile($file, $providerName)
{
$type = false;
$nfile = 'public'.$file;
$providerName = "MyApp\\Conciliation\\".$providerName;
$provider = new $providerName();
$provider->equalize($nfile);
}
http://php.net/manual/en/language.namespaces.dynamic.php
If you are calling the class dynamically, you have to use the full path to the class.
So, your call to equalizeFile should be something like:
equalizeFile("myFile", "MyApp\\Conciliation\\Gol");

Register class methods with nusoap

I've a php class and i want to use it with Nusoap. Can I register the class method's that already exists inside the nusoap with the register command?
Sample :
Here we register a function that we defined inside this script. But if we've a class that we maybe develop months ago and we want to use it as a webservice using the WSDL. Is there a way to register the methods of that class so that Nusoap creates a WSDL of it's stucture (methods inside)?
require_once("nuSOAP/lib/nusoap.php");
$server = new soap_server();
$namespace = "http://localhost/nusoapSCRIPT/index.php";
$server->wsdl->schemaTargetNamespace = $namespace;
$server->configureWSDL("SAMPLE");
$server->register('HelloWorld');
function HelloWorld()
{
return "Hello, World!";
}
Well here's how i solve this... maybe someone can try an approach in another way.
[File : index.php]
require_once "nuSOAP/lib/nusoap.php";
require_once "myClass.class.inc.php";
$namespace = "http://localhost/html/nusoap/index.php";
// create a new soap server
$server = new soap_server();
// configure our WSDL
$server->configureWSDL("Class Example");
// set our namespace
$server->wsdl->schemaTargetNamespace = $namespace;
// register the class method and the params of the method
$server->register("myClass.ShowString"
,array('name'=>'xsd:string')
,array('return'=>'xsd:string')
,$namespace,false
,'rpc'
,'encoded'
,'Sample of embedded classes...'
);
//
// Get our posted data if the service is being consumed
// otherwise leave this data blank.
$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA'])
? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
// pass our posted data (or nothing) to the soap service
$server->service($POST_DATA);
exit();
and the class code.
[File 'myClass.class.inc.php']
class myClass{
public function __construct(){
}
public function ShowString($mens){
return "\n##Remote Class :".__CLASS__."\n##Remote Method : ".__METHOD__."\n## mSG :{$mens}";
}
}
I also create a soap client in c# and it consumes correctly the soap service.
Hope this help!
You can call the method using getProxy()
$proxy->className__methodname

Categories