Zend 2 How to Disable shared instantiation of services on the fly - caching

In Zend 2, we use the function get() to get the same instance of a service when we request it multiple times. It is created the first time and cached during the request. That's what a shared service is.
$ar = $this->serviceLocator->get('ActionResponsibility');
Now a non-shared service will create a new instance every time it is requested. to do this we have to change the configuration file as following:
<?php
return [
'service_manager' => [
'invokables' => [
'MyService' => 'Application\Service\MyService',
'AnotherService' => 'Application\Service\AnotherService',
],
'shared' => [
'MyService' => false,
'AnotherService' => false,
'ThirdPartyService' => true,
],
// [...]
]
];
The Questions is, how can we get a new instance only when required in the code, isn't there a way in using the get() function to force a new instance instead of a cached copy?

You can use the build method instead of get to retrieve a new non cached instance.
$ar = $this->serviceLocator->build('ActionResponsibility');

Related

How to Fix Client Error: file_get_contents(): in Cpanel with Laravel Project inside

i have problem when do seed in my laravel project in cpanel.
this is the errors
Client Error: file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0
at vendor/kavist/rajaongkir/src/HttpClients/BasicClient.php:74
70▕
71▕ private function executeRequest(string $url): array
72▕ {
73▕ set_error_handler(function ($severity, $message) {
➜ 74▕ throw new BasicHttpClientException('Client Error: '.$message, $severity);
75▕ });
76▕
77▕ $rawResponse = file_get_contents($url, false, $this->context);
Please Someone help me
this is my LocationsTableSeeder.php
public function run()
{
$daftarProvinsi = RajaOngkir::provinsi()->all();
foreach ($daftarProvinsi as $provinceRow) {
Province::create([
'province_id' => $provinceRow['province_id'],
'nama' => $provinceRow['province'],
]);
$daftarKota = RajaOngkir::kota()->dariProvinsi($provinceRow['province_id'])->get();
foreach ($daftarKota as $cityRow) {
Kabupaten::create([
'province_id' => $provinceRow['province_id'],
'city_id' => $cityRow['city_id'],
'nama' => $cityRow['city_name'],
'type' => $cityRow['type'],
'postal_code' => $cityRow['postal_code'],
]);
}
}
}
It's a good practice to disable file_get_contents ability to open remote URLs (like the ones starting HTTP) on shared servers (that frequently use Cpanel) to avoid the download/injection of malicious scripts in your server.
Go to Cpanel PHP options and enable allow_url_fopen, as pointed by apokryfos, usually it's at Switch To PHP Options menu. Some providers will not allow this change via Cpanel and you might need to open a support ticket.
Usually, this option cannot be changed by ini_set or via the PHP script itself in any other way.

CakePHP 3.x ORM doesn't use cache data when key exists

CakePHP 3.5.13 with Redis configured as the cache engine:
// config/app.php
'Cache' => [
'default' => [
'className' => 'Redis',
'duration' => '+1 hours',
'prefix' => 'cake_redis_',
'host' => '127.0.0.1',
'port' => 6379,
],
];
I have a table with ~260,000 rows in it and a corresponding Table class called SubstancesTable.php. I'm attempting to get the first 5000 rows and then cache the results, so that on subsequent queries, the cached results are used rather than executing the same query:
// Controller method
public function test()
{
$this->autoRender = false;
$Substances = TableRegistry::get('Substances');
// Get 5000 rows from table
$query = $Substances->find('list')->limit(5000);
// Write to cache
$query->cache('test_cache_key');
// Output the results
debug($query->toArray());
}
When I login to Redis (running redis-cli through ssh on my webserver), I can see a key has been generated with the name "test_cache_key":
127.0.0.1:6379> KEYS *
1) "cake_redis_test_cache_key"
I can also see the serialized data in there using GET cake_redis_test_cache_key.
When I execute the above in a browser, there is virtually no difference in the time taken between the cache not existing, and after the cache has been created. I have deleted the cached key in Redis using DEL cake_redis_test_cache_key and confirmed it has gone by listing the keys in Redis (KEYS *)
Clearly Cake isn't reading from the cache in this situation, even though it's writing to it without problems. Why is this happening?
The documentation (https://book.cakephp.org/3.0/en/orm/query-builder.html#caching-query-results) is not clear. Do I need to do something else to get it to read the results from the cache? I've also read CakePHP 3: find() with cache but can't see what's being done differently to what I'm doing above.

Hybridauth + composer: how to add custom providers

I'm converting a php project to use composer as dependency manager.
The dependencies are loaded via this line in my main script.
require 'vendor/autoload.php';
One of these dependencies is hybridauth (version 2.9). Since using Composer, it throws 'file not found' errors when looking for custom providers files.
For instance, my main controller calls Hybrid like this:
$config_file_path = dirname(__FILE__) .'/hybridauth/config.php';
$hybridauth = new Hybrid_Auth( $config_file_path );
Now, here is the config file. The provider i'm using is "Facebooktest".
Note that I had to specify the path via the [wrapper][path]; array key to get to the next error message.
return
array(
"base_url" => WWWROOT."/auth",
"providers" => array(
"Facebook" => array(
"enabled" => true,
"keys" => array("id" => "xxxxxxx", "secret" => "xxxxxxxx"),
"scope" => "email",
"trustForwarded" => false
),
"Facebooktest" => array(
"enabled" => true,
"keys" => array("id" => "xxxxxxx", "secret" => "xxxxxx"),
"scope" => "email",
"trustForwarded" => false,
"wrapper"=> array(
"class"=>'Hybrid_Providers_Facebooktest',
"path"=> './controllers/hybridauth/Hybrid/Providers/Facebooktest.php'
)
)
),
"debug_mode" => false,
"debug_file" => "",
);
The error message (with trace):
require_once(/path/to/composer-project/vendor/hybridauth/hybridauth/hybridauth/Hybrid/thirdparty/Facebook/autoload.php): failed to open stream: No such file or directory
[vendor/bcosca/fatfree/lib/base.php:2174] Base->error()
[controllers/hybridauth/Hybrid/Providers/Facebooktest.php:61] Base->{closure}()
[controllers/hybridauth/Hybrid/Providers/Facebooktest.php:61] require_once()
[vendor/hybridauth/hybridauth/hybridauth/Hybrid/Provider_Model.php:99] Hybrid_Providers_Facebooktest->initialize()
[vendor/hybridauth/hybridauth/hybridauth/Hybrid/Provider_Adapter.php:101] Hybrid_Provider_Model->__construct()
[vendor/hybridauth/hybridauth/hybridauth/Hybrid/Auth.php:278] Hybrid_Provider_Adapter->factory()
[vendor/hybridauth/hybridauth/hybridauth/Hybrid/Auth.php:230] Hybrid_Auth::setup()
[controllers/auth-action.get.php:19] Hybrid_Auth::authenticate()
I find it strange that I now need to modify paths inside the "vendor/hybridauth/" project. It defeats the purpose of using a dependency manager. Surely, I must be doing it wrong.
Can you advise?
Check my answer to another question here
If you have recently installed Hybridauth through composer you probably have downloaded v2.9.2, which contain a bug in their Facebook class that replace the vendor path from yours to hybridauth/vendor, causing such issue.
I suspect you created that Facebooktest class by copying their Facebook class and therefore sustained that error. Either update to their dev branch and copy that Facebook class, or simply use other provider class as template for your custom provider class.

How can I extend the default session duration in Concrete 5.7?

How can I extend the default duration of sessions in the Concrete5 CMS (v5.7)? It feels like I have to login again way too frequently.
One way I discovered to achieve this is by modifying the session-handling settings inside /application/config/concrete.php:
return [
//----------------------- SUPER LONG SESSIONS -------------------------
// We want to extend the session cookie to last for 4 months
// so that users are not bugged for their password all the time.
// WARNING: This does reduce security and potentially increase the chance of
// session-hijacking but if you're willing to make the trade-off, here goes
'session' => [
'name' => 'CONCRETE5',
'handler' => 'file',
// We'll use our own specific save_path so that others on our
// server don't garbage-collect our sessions
'save_path' => DIR_APPLICATION . '/files/tmp/sessions',
// 40 days (in seconds). This is a timeout value.
// If session is not used for 40 days, it is likely to be garbage collected
'max_lifetime' => 3456000,
'cookie' => [
'cookie_path' => false,
// This defaults to 0 which is a session cookie
// (ends when browser is closed)
// Extending to last 4 months (in seconds). Cookie will span multiple
// browser restarts up until this max value, and then user will be forced
// to login again (yes, even in the middle of a session, beware!)
'cookie_lifetime' => 10510000,
'cookie_domain' => false,
'cookie_secure' => false,
'cookie_httponly' => true
]
],
// Browser user-agents and IP addresses may change within that time
// so we will disable strict checking for those
'security' => [
'session' => [
'invalidate_on_user_agent_mismatch' => false,
'invalidate_on_ip_mismatch' => false
],
]
];
Sidenote:
The specific groups a member is a part of are stored in the session and only refreshed when logging in, or when certain permissions are changed in the Dashboard. When this occurs, Concrete5 automatically updates the timestamp in /application/config/generated_overrides/concrete.php, but you can also do this manually if you want to force users' permissions to be refreshed mid-session:
return array(
...
'misc' => array(
'access_entity_updated' => 1453869371,
),

Using Yii2's default messages

I can't figure out, how to use Yii's default messages, without overwriting them with the message command.
I have 2 translation categories: app, data.
I'd like to use the default messages, like "Are you sure you want to delete this item?" and "(not set)" from the Yii2 core, but if I use Yii::t('yii', 'Are you sure you want to delete this item?') and then run the yii message command, it creates a yii.php file in the messages folder with this token.
Part of my config:
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
],
'data*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
],
],
],
How should I set up my config to use the built in texts and not to overwrite them?
You don't have to do anything. The yii-category is automatically defined as soon as you use translation and it points to the messages in the framework.
That it creates an empty file is for 'yii' is normal, because you actually use that category in your code. This is unrelated to where the messages will be loaded from during normal execution.
Just make sure that you configure your apps' language and sourceLanguage correctly if not already done.

Resources