Situation:
This is the screen message I became after installing tikiwiki 24.
Fatal error: Declaration of Symfony\Component\DependencyInjection\Loader\XmlFileLoader::load($resource, ?string $type = NULL) must be compatible with Symfony\Component\Config\Loader\LoaderInterface::load($resource, $type = NULL) in /var/www/contiki/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php on line 46
So please, does anyone have a clue what's going on here? I'm quite new to composer, solved many compatibility issues but this is out of my range.
I don't understand why they are incompatible.
These are (part) of the files:
My /var/www/contiki/vendor_bundled/vendor/symfony/config/Loader/LoaderInterface.php
interface LoaderInterface
{
/**
* Loads a resource.
*
* #param mixed $resource The resource
* #param string|null $type The resource type or null if unknown
*
* #throws \Exception If something went wrong
*/
public function load($resource, $type = null);
/**
* Returns whether this class supports the given resource.
*
* #param mixed $resource A resource
* #param string|null $type The resource type or null if unknown
*
* #return bool True if this class supports the given resource, false otherwise
*/
public function supports($resource, $type = null);
/**
* Gets the loader resolver.
*
* #return LoaderResolverInterface A LoaderResolverInterface instance
*/
public function getResolver();
/**
* Sets the loader resolver.
*/
public function setResolver(LoaderResolverInterface $resolver);
}
The first part of the /var/www/contiki/vendor_bundled/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php file
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\ExpressionLanguage\Expression;
/**
* XmlFileLoader loads XML files service definitions.
*
* #author Fabien Potencier <fabien#symfony.com>
*/
class XmlFileLoader extends FileLoader
{
const NS = 'http://symfony.com/schema/dic/services';
/**
* {#inheritdoc}
*/
public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);
$xml = $this->parseFileToDOM($path);
$this->container->fileExists($path); <-- This is rule 46
$defaults = $this->getServiceDefaults($xml, $path);
// anonymous services
$this->processAnonymousServices($xml, $path, $defaults);
// imports
$this->parseImports($xml, $path);
// parameters
$this->parseParameters($xml, $path);
// extensions
$this->loadFromExtensions($xml);
// services
try {
$this->parseDefinitions($xml, $path, $defaults);
} finally {
$this->instanceof = [];
}
}```
Sounds like something's got tangled up here, Tiki 24 is not out yet but will be branching soon, so if you want a stable safe Tiki now, probably best to use a stable released branch, i.e. 23.x? Also, we are still on Smarty 3.x and plan to upgrade to 4.x (and PHP 8+) after the release of 24 which is our next LTS version, so not sure where that is coming from... did you run sh setup.sh?
As Nico said above, this is probably more Tiki-specific than is suitable for here, so the best thing would be to come and chat with the community in our new Gitter room, here?
Welcome to Tiki! :)
I have a small problem in my laravel API deployed in heroku, that started to happen to me from nowhere, without updating anything or making any relevant changes, and it happens to me when I try to use any eloquent resource, for example when doing:
$brands = Brand::paginate(15);
return BrandResource::collection($brands);
I get this error:
array_key_exists(): Using array_key_exists() on objects is deprecated. Use isset() or property_exists() instead
in DelegatesToResource.php line 49
Investigating a bit, get to the file: DelegatesToResource.php in vendor, and in effect it use:
public function offsetExists($offset)
{
return array_key_exists($offset, $this->resource);
}
To make a test, I created a new Laravel project, and in fact it comes with that line already corrected, like this:
public function offsetExists($offset)
{
return isset($this->resource[$offset]);
}
If there is any way to solve this in my project, I understand that I should not and cannot change files in vendor, so my question is what to do in this case?
I´m using Laravel Framework 5.6.39 and PHP 7.2.18 (cli)
Solution 1
Add updated code to your BrandResource so it may appear like this:
class BrandResource extends JsonResource
{
/**
* Determine if the given attribute exists.
*
* #param mixed $offset
* #return bool
*/
public function offsetExists($offset)
{
return isset($this->resource[$offset]);
}
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}
Solution 2
If you are paginating your data in multiple resources then it's better to extend custom class which contains this updated function rather than extending JsonResource directly.
So it'll look like this:
class CustomResource extends JsonResource
{
/**
* Determine if the given attribute exists.
*
* #param mixed $offset
* #return bool
*/
public function offsetExists($offset)
{
return isset($this->resource[$offset]);
}
}
And Use on your resources like:
class BrandResource extends CustomResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}
Trying to use a package to handle my requests to the Facebook API. Getting this error, and not sure where to start.
Here is the package:
https://github.com/edbizarro/laravel-facebook-ads
Here is what i'm doing...
$adsApi = FacebookAds::init($accessToken);
$adAccounts = $adsApi->adAccounts();
$adAccounts->all(['account_id', 'balance', 'name']);
Here is the error:
ErrorException (E_USER_DEPRECATED)
assureEndpoint is being deprecated, please try not to use this in new code.
You should use the getEndpoint instead of this.
They have mentioned this in the sdk files on line 360 of
https://github.com/facebook/facebook-php-business-sdk/blob/master/src/FacebookAds/Object/AbstractCrudObject.php
/**
* #deprecated
* deprecate with getEndpoint
* #param string $prototype_class
* #param string $endpoint
* #return string
* #throws \InvalidArgumentException
*/
protected function assureEndpoint($prototype_class, $endpoint) {
.....
}
I am looking for a function in PHP, which makes the same as Perl's Net::CIDR::range2cidr function.
I found some solutions in Google:
tutorialspots - ip2cidr (Not working correctly for ['10.0.0.0', '10.255.255.255'])
tutorialspots - cidr2ip (Not working correctly for "192.168.1.15/24")
flygoast/range2cidr (Must be installed)
Is there an easier way to convert CIDR to range and back ?
(Maybe, did I just miss an existing function in PHP ?)
Solved it using the s1lentium/iptools composer package and the following code:
/**
* Perl's "Net::CIDR::range2cidr()" function.
*
* #param string $from
* #param string $to
*
* #return array
*/
function range2cidr($from, $to) {
$networks = IPTools\Range::parse("{$from}-{$to}")->getNetworks();
return array_map(function(IPTools\Network $network) {
return (string)$network;
}, $networks);
}
/**
* #param string $cidr
*
* #return array
*/
function cidr2range($cidr) {
/** #var IPTools\Range $range */
$range = IPTools\Network::parse($cidr)->hosts;
return [
(string)$range->getFirstIP(),
(string)$range->getLastIP(),
];
}
I'm developing a so called AAC (Automatic Account Creator) for a game, it's basically a site with functions to create accounts, players and several more things for players. The server only supports SHA1 and plain - which is totally unsafe. I can't dive into the source code and make changes. If there's anyway to use SHA1 I would be grateful. I just read about BCrypt, it's great but I can't really change the source code to suit BCrypt. I managed to put SHA1 on registration like this:
$password = $input['password'];
$password = sha1($password);
But I simply can't login. am I doing it wrong? seems like Laravel won't let me login.
I've got get_register and post_register, also I've got get_login and post_login. Do i need to change something in the post_login to make it login or?
any hints?
I'm using Laravel's php server (php artisan serve) and phpMyAdmin on WAMP. I think Laravel checks when you are checking the DB via the Auth::attempt method laravel is doing some form of hashing to check the current pw and the logged in one to check against each other.
You'll have to rewrite the Hash module. Thanks to Laravel's ideas of following IoC and Dependency Injection concepts, it'll be relatively easy.
First, create a app/libraries folder and add it to composer's autoload.classmap:
"autoload": {
"classmap": [
// ...
"app/libraries"
]
},
Now, it's time we create our class. Create a SHAHasher class, implementing Illuminate\Hashing\HasherInterface. We'll need to implement its 3 methods: make, check and needsRehash.
Note: On Laravel 5, implement Illuminate/Contracts/Hashing/Hasher instead of Illuminate\Hashing\HasherInterface.
app/libraries/SHAHasher.php
class SHAHasher implements Illuminate\Hashing\HasherInterface {
/**
* Hash the given value.
*
* #param string $value
* #return array $options
* #return string
*/
public function make($value, array $options = array()) {
return hash('sha1', $value);
}
/**
* Check the given plain value against a hash.
*
* #param string $value
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function check($value, $hashedValue, array $options = array()) {
return $this->make($value) === $hashedValue;
}
/**
* Check if the given hash has been hashed using the given options.
*
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function needsRehash($hashedValue, array $options = array()) {
return false;
}
}
Now that we have our class done, we want it to be used by default, by Laravel. To do so, we'll create SHAHashServiceProvider, extending Illuminate\Support\ServiceProvider, and register it as the hash component:
app/libraries/SHAHashServiceProvider.php
class SHAHashServiceProvider extends Illuminate\Support\ServiceProvider {
/**
* Register the service provider.
*
* #return void
*/
public function register() {
$this->app['hash'] = $this->app->share(function () {
return new SHAHasher();
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides() {
return array('hash');
}
}
Cool, now all we have to do is make sure our app loads the correct service provider. On app/config/app.php, under providers, remove the following line:
'Illuminate\Hashing\HashServiceProvider',
Then, add this one:
'SHAHashServiceProvider',
It took me a lot of time to get something similar happening in Laravel 5.6 but this thread was invaluable. The accepted answer gets you very close but there are still some ambushes along the way (as can be seen in the comments) so instead of struggling with the comments I thought it would be helpful for others to have it presented as an answer.
In my case I needed to access an existing database and couldn't change the user file. The passwords were saved in SHA256 format with a hash key applied as well. So the objective for me was to really only get the check function working.
I'm really new to Laravel and I know there will be a better way around this issue but I couldn't get the app\Libraries area to register so I put both SHAHasher.php and SHAHashServiceProvider.php into app\Providers which I would assume is some sort of Laravel sacrilege but it was the only way I got it to work. :)
The steps I took (hijacking rmobis's excellent answer for Laravel 4) was:
The hash key used in the original app needed to be accessed by Laravel so I added this to the bottom of .env.
.env
...
HASH_KEY=0123_key_code_added_here_xyz
app/Providers/SHAHasher.php
namespace App\Providers;
use Illuminate\Contracts\Hashing\Hasher;
class SHAHasher implements Hasher
{
/**
* Get information about the given hashed value.
* TODO: This was added to stop the abstract method error.
*
* #param string $hashedValue
* #return array
*/
public function info($hashedValue)
{
return password_get_info($hashedValue);
}
/**
* Hash the given value.
*
* #param string $value
* #return array $options
* #return string
*/
public function make($value, array $options = array())
{
// return hash('sha1', $value);
// Add salt and run as SHA256
return hash_hmac('sha256', $value, env('HASH_KEY'));
}
/**
* Check the given plain value against a hash.
*
* #param string $value
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function check($value, $hashedValue, array $options = array())
{
return $this->make($value) === $hashedValue;
}
/**
* Check if the given hash has been hashed using the given options.
*
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function needsRehash($hashedValue, array $options = array())
{
return false;
}
}
app/Providers/SHAHashServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class SHAHashServiceProvider extends ServiceProvider {
/**
* Register the service provider.
*
* #return void
*/
public function register() {
$this->app->singleton('hash', function() {
return new SHAHasher();
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides() {
return array('hash');
}
}
app/config/app.php
remove or comment out // Illuminate\Hashing\HashServiceProvider::class,
Add App\Providers\SHAHashServiceProvider::class,
I didn't need to register the users (only to allow them to use their existing logins to get in) so I only tested it for access. I'm not sure why the app/Libraries area wouldn't take. I was getting an error
Class 'SHAHashServiceProvider' not found
when I ran the composer dump-autoload command until I moved both into app/Providers.
Hope this helps others trying to get the anser to work in Laravel 5.
There is actually a easier (or more simple, at least) solution for a case like this. you can 'fake' the hashing, by using this method in the user model:
public function getAuthPassword() {
return Hash::make($this->password);
}
And hashing the input with your own hash function. For instance, if your passwords are currently hashed with sha1, you can validate the user with
Auth::attempt(array('email' => $email, 'password' => sha1($password))
It doesn't feel like good coding practice, to do it this way, but it will certainly be easier than rewriting the hash module.
The Laravel 7 way
In Laravel 7 adding new hash methods to Laravel got a lot easier you can also still support the old Hash methods instead of basically overwriting them.
First we will create a subfolder in the app folder called Libs or Libaries or basically whatever you want to call it.
In that folder I created a folder called CustomHash where I store all my custom hashers.
Through PSR-4 it is automatically detected and we do not need to add it anywhere.
The Namespace is based on the folder names I chose.
app/AppServiceProvider.php
First we use the namespace of the Sha1Hasher
use App\Libs\CustomHash\Sha1Hasher;
then in the boot() function of your AppServiceProvide.php
Hash::extend("sha1", function($app)
{
return new Sha1Hasher();
});
app/Libs/CustomHash/Sha1Hasher.php
<?php
namespace App\Libs\CustomHash;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Hashing\AbstractHasher;
class Sha1Hasher extends AbstractHasher implements HasherContract {
/**
* Hash the given value.
*
* #param string $value
* #return array $options
* #return string
*/
public function make($value, array $options = array()) {
//I have custom encoding / encryption here//
//Define your custom hashing logic here//
return sha1($value);
}
/**
* Check the given plain value against a hash.
*
* #param string $value
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function check($value, $hashedValue, array $options = array()) {
return $this->make($value) === $hashedValue;
}
/**
* Check if the given hash has been hashed using the given options.
*
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function needsRehash($hashedValue, array $options = array()) {
return false;
}
}
And that's basically it if you want to change the default hash algorithm for everything there is one more thing to do:
config/hashing.php
Change the default driver for hashing to the sha1 driver we implemented with the edits above.
'driver' => 'sha1',
You can do this
dd(
sha1(55),
hash('sha1', 55),
hash_hmac('sha1', 55, env('APP_KEY')),
hash_hmac('sha256', 55, env('APP_KEY')),
hash_hmac('sha512', 55, env('APP_KEY')),
);
// outputs:
/*
"8effee409c625e1a2d8f5033631840e6ce1dcb64"
"8effee409c625e1a2d8f5033631840e6ce1dcb64"
"a2ebb15e6747d1c09f2754787ab390d35c24996e"
"f0fadaa9fdd518947ac3f698196d5370dc2409bbdfbe9e37bd30f935b6cc1f47"
"c1e6f4e144565aa4fdb9c7ae34aba7d43424e20fa40ad3a0641d20bfbb3b9681ded4f4cc8b4661804e4a753118a3f984585d6915ee6d4b75a95310af48afe920"
*/
Laravel 7 UPD
same as Das123 answer but a little fix to
app/Providers/SHAHashServiceProvider.php
namespace App\Libraries\ShaHash;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Hashing\AbstractHasher;
class SHAHasher extends AbstractHasher implements HasherContract
/**
* Register the service provider.
*
* #return void
*/
public function register() {
$this->app->singleton('hash', function() {
return new SHAHasher();
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides() {
return array('hash');
}
}