<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\ErrorHandler\ErrorEnhancer;
use Composer\Autoload\ClassLoader;
use Symfony\Component\ErrorHandler\DebugClassLoader;
use Symfony\Component\ErrorHandler\Error\ClassNotFoundError;
use Symfony\Component\ErrorHandler\Error\FatalError;
/**
* @author Fabien Potencier <fabien@symfony.com>
*/
class ClassNotFoundErrorEnhancer implements ErrorEnhancerInterface
{
/**
* {@inheritdoc}
*/
public function enhance(\Throwable $error): ?\Throwable
{
// Some specific versions of PHP produce a fatal error when extending a not found class.
$message = !$error instanceof FatalError ? $error->getMessage() : $error->getError()['message'];
if (!preg_match('/^(Class|Interface|Trait) [\'"]([^\'"]+)[\'"] not found$/', $message, $matches)) {
return null;
}
$typeName = strtolower($matches[1]);
$fullyQualifiedClassName = $matches[2];
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
$className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
$namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
$message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
$tail = ' for another namespace?';
} else {
$className = $fullyQualifiedClassName;
$message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
$tail = '?';
}
if ($candidates = $this->getClassCandidates($className)) {
$tail = array_pop($candidates).'"?';
if ($candidates) {
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
} else {
$tail = ' for "'.$tail;
}
}
$message .= "\nDid you forget a \"use\" statement".$tail;
return new ClassNotFoundError($message, $error);
}
/**
* Tries to guess the full namespace for a given class name.
*
* By default, it looks for PSR-0 and PSR-4 classes registered via a Symfony or a Composer
* autoloader (that should cover all common cases).
*
* @param string $class A class name (without its namespace)
*
* Returns an array of possible fully qualified class names
*/
private function getClassCandidates(string $class): array
{
if (!\is_array($functions = spl_autoload_functions())) {
return [];
}
// find Symfony and Composer autoloaders
$classes = [];
foreach ($functions as $function) {
if (!\is_array($function)) {
continue;
}
// get class loaders wrapped by DebugClassLoader
if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();
if (!\is_array($function)) {
continue;
}
}
if ($function[0] instanceof ClassLoader) {
foreach ($function[0]->getPrefixes() as $prefix => $paths) {
foreach ($paths as $path) {
$classes[] = $this->findClassInPath($path, $class, $prefix);
}
}
foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {
foreach ($paths as $path) {
$classes[] = $this->findClassInPath($path, $class, $prefix);
}
}
}
}
return array_unique(array_merge([], ...$classes));
}
private function findClassInPath(string $path, string $class, string $prefix): array
{
if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.\dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
return [];
}
$classes = [];
$filename = $class.'.php';
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
$classes[] = $class;
}
}
return $classes;
}
private function convertFileToClass(string $path, string $file, string $prefix): ?string
{
$candidates = [
// namespaced class
$namespacedClass = str_replace([$path.\DIRECTORY_SEPARATOR, '.php', '/'], ['', '', '\\'], $file),
// namespaced class (with target dir)
$prefix.$namespacedClass,
// namespaced class (with target dir and separator)
$prefix.'\\'.$namespacedClass,
// PEAR class
str_replace('\\', '_', $namespacedClass),
// PEAR class (with target dir)
str_replace('\\', '_', $prefix.$namespacedClass),
// PEAR class (with target dir and separator)
str_replace('\\', '_', $prefix.'\\'.$namespacedClass),
];
if ($prefix) {
$candidates = array_filter($candidates, function ($candidate) use ($prefix) { return str_starts_with($candidate, $prefix); });
}
// We cannot use the autoloader here as most of them use require; but if the class
// is not found, the new autoloader call will require the file again leading to a
// "cannot redeclare class" error.
foreach ($candidates as $candidate) {
if ($this->classExists($candidate)) {
return $candidate;
}
}
try {
require_once $file;
} catch (\Throwable $e) {
return null;
}
foreach ($candidates as $candidate) {
if ($this->classExists($candidate)) {
return $candidate;
}
}
return null;
}
private function classExists(string $class): bool
{
return class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);
}
}
Initiates a new payment transaction.
create-order
| Parameter | Type | Details |
|---|---|---|
| amount | decimal | Your Amount , Must be rounded at 2 precision. |
| currency | string | Currency Code, Must be in Upper Case (Alpha-3 code) |
| success_url | string | Enter your return or success URL |
| cancel_url | string (optional) | Enter your cancel or failed URL |
Request Example (guzzle)
<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $base_url.'create-order', [
'headers' => [
'Authorization' => 'Bearer '. $authorizationToken,
'accept' => 'application/json',
'content-type' => 'application/json',
],
'form_params' => [
'amount' => '$amount',
'currency' => 'currency',
'success_url' => 'success_url',
'cancel_url' => 'cancel_url',
],
]);
echo $response->getBody();
**Response: SUCCESS (200 OK)**
{
"message": {
"success": [
"Order created successfully."
]
},
"data": {
"redirect_url":"https://example.com/login/OISADFDFSDFSF",
"order_details":{
"amount" : "10",
"fixed_charge" : 2,
"percent_charge" : 1,
"total_charge" : 3,
"total_payable" : 13,
"currency" : "USD",
"expiry_time": "2024-04-25T06:48:35.984285Z",
"success_url": "http://127.0.0.1/nfcpay/user/transaction/success",
"cancel_url": "http://127.0.0.1/nfcpay/user/transaction/cancel"
}
},
"type": "success"
}
**Response: ERROR (400 FAILED)**
{
"message": {
"error": [
"Invalid token."
]
},
"data": null,
"type": "error"
}