Is it possible to make Yii2 call a function when executing php init? - yii2

I'm wondering if it's possible in Yii2 to call a function automatically when executing php init command?
I have a component/extension which has a function that I want to call only when the Yii2 app is initialized. Can this function be registered in anywhere so that it will be automatically called and is it even possible?

init (Yii Application Initialization Tool) is available for Advanced Application Template only and written in procedural style (not OOP).
Unfortunately, init does not raise any events, so you can't add any event handlers to execute custom code.
The easiest way to solve the problem is to modify init file itself, but it's not good practice, because changes can be lost on framework update (file is included in git trackable files in framework core).
My advice will be create separate console command for handling that and execute it right after php init:
php init your-custom-console-controller/action-name
If you are using deploy tools, such as Deployer, you can easily add your custom command for execution right after init.
Recipe for Yii2 Advanced Application Template exists, so you can add your custom command like so:
task('deploy:your_custom_command', function () {
cd('{{release_path}}');
run('php yii your-custom-console-controller/action-name');
});
after('deploy:init', 'deploy:your_custom_command');
Then you just run:
dep deploy production
And forget about everything what you need to do to deploy your project.
Definetely recommend to spend some time and learn it, it's worth it.

Related

Show error when a function is called inside / outside of certain folders

Is there a way to, for example, make PhpStorm show an error (on the function call and for the file) when function xyx() is called in any file in any folder other than in folder abc?
Specific use case if it helps:
I want to show an error where ever I use the env() function outside of the config folder in a Laravel app - because, after running php artisan config:cache, which one does when deploying a Laravel app, all calls to env() return null, and I'm worried it's easy to accidentally use env() in my codebase rather than config()

Filemaker - how/where to use custom function?

I have downloaded the BaseElements plugin for Filemaker and managed to get it installed, I have downloaded this specifically to make use of "BE_ExportFieldContents" (https://baseelementsplugin.zendesk.com/hc/en-us/articles/204700538-BE-ExportFieldContents) which basically allows me to export from a Container field on a server side script. I have looked through the documentation and cannot seem to find help.
Now I have the function, I'm completely at a loss on how to actually call the function? I want to export something from the container file to the filemaker documents path - so my question is, where and how the hell do I use this function in Filemaker? Apologies in advance for the noob question.
You make a script where you call this function from the record in question. This script can be run in the client, or via a schedule on FileMaker Server or via the Perform Script on Server script step.
The syntax is like this:
BE_ExportFieldContents ( field ; outputPath )
Where the ‘field’ parameter is the container field and the ‘outputPath’ is where you want the file to end up.
Usually you call such functions via the Set Variable script step. After the execution the variable contains any error or result from the call.
Note that the plugin needs to be installed and enabled on the server for it to work there.

MediaWiki Hook for Installing Extension

I did some research on MediaWiki hooks.
To the best of my knowledge, the only hook for adding/updating database tables is https://www.mediawiki.org/wiki/Manual:Hooks/LoadExtensionSchemaUpdates.
However, I need a hook that fires on installing a new extension. How do I achieve that? I'd like to execute a CREATE TABLE statement only once - when the extension is installed. Installing an extension doesn't require a MediaWiki update, which is why the above hook does not suit my needs.
EDIT
To clarify: I'm developing an extension that requires access to a custom table in the database. That's why I need to execute the CREATE TABLE statement whenever this extension is installed.
First: As you have noticed, there is no such hook. You will need to do the check for installed extensions by a cron job (if it's your server), or on, say, each 100th request to the wiki, using the job queue (if you are doing this in an extension).
From there, you have a few options, depending on if you need to catch every single extension, or just most of them:
Check for registered extensions, with something like: $registry = ExtensionRegistry::getInstance();$extensions = $registry->loaded();This will work extensions using the new style. For older versions, check the global variable $wgExtensionCredits for registered extensions. Note that nothing prevents an extensions from running without registering. In fact, there are a lot of extensions like that.
Parse LocalSettings.php, and check for old and new style extension loading with a regex. Very dirty, but it's actually the way e.g. the maintainance script getConfiguration.php does it. You need to check for lines like this:wfLoadExtension( 'FooBar' );and this:wfLoadExtensions( ['Foo', 'Bar'] );and this:require_once "$IP/extensions/Foo/Bar.php"; Note however that it is possible to use other directories for extensions, and that modern skins in fact behave like extensions too.
If you need to track a certain family of extensions, and you can make sure they all use Composer, the parse $IP/composer.json for installed extensions.
I did some more research (https://www.mediawiki.org/wiki/Manual:Update.php#Details) and found out that the LoadExtensionSchemaUpdates hook is exactly what I am looking for.
# Schema updates for update.php
$wgHooks['LoadExtensionSchemaUpdates'][] = 'fnMyHook';
function fnMyHook( DatabaseUpdater $updater ) {
$updater->addExtensionTable( 'tablename',
__DIR__ . '/table.sql' );
return true;
}
When running $ php update.php for the first time after installing the extension, the script executes the CREATE TABLE statement. Then, for consecutive executions, the update script just notes that the table already exists.

Using CakePHP 3.0 plugin

I'm currently building a new CakePHP app with version 3.0.0-RC1, and trying to install and use the jasig/phpCAS plugin. Using this guide, I've run the following command from the command prompt: composer require jasig/phpcas
This correctly copies the jasig/phpcas files into the vendor directory of my app, but one of the other files that the guide says should be updated (vendor/cakephp-plugins.php) doesn't even exist.
I've had a tough time accessing the plugin. I want to be able to call its static methods, and I keep getting errors of the form: Error: Class 'App\Controller\phpCAS' not found. (The exact directory in the error changes depending on where I'm calling the method from.)
I don't know if this is due to not having the cakephp-plugins.php file, or if I'm not calling the plugin correctly. It's my understanding that if the plugin is loaded I should just be able to call static methods on it like this: phpCAS::methodName()
First of all jasig/phpcas is not a CakePHP plugin. And the vendor/cakephp-plugins.php file is created by the CakePHP plugin installer, so if you don't see such a file, you seem to have either not installed any plugins yet, or you are not using a recent version of the installer, as the creation of this file has been introduced just recently.
Regarding the error about the class not being found, you are missing the leading namespace separator (\phpCAS::methodName()) to access the class in the global namespace, respectively you are missing a proper import (use phpCAS;) that would make the class available in the current namespace.
In case you are not familiar with namespaces, you may want to start with: http://php.net/namespaces

How can I get a Windows batch or Perl script to run when a file is added to a directory?

I am trying to write a script that will parse a local file and upload its contents to a MySQL database. Right now, I am thinking that a batch script that runs a Perl script would work, but am not sure if this is the best method of accomplishing this.
In addition, I would like this script to run immediately when the data file is added to a certain directory. Is this possible in Windows?
Thoughts? Feedback? I'm fairly new to Perl and Windows batch scripts, so any guidance would be appreciated.
You can use Win32::ChangeNotify. Your script will be notified when a file is added to the target directory.
Checking a folder for newly created files can be implemented using the WMI functionality. Namely, you can create a Perl script that subscribes to the __InstanceCreationEvent WMI event that traces the creation of the CIM_DirectoryContainsFile class instances. Once that kind of event is fired, you know a new file has been added to the folder and can process it as you need.
These articles provide more information on the subject and contain VBScript code samples (hope it won't be hard for you to convert them to Perl):
How Can I Automatically Run a Script Any Time a File is Added to a Folder?
WMI and File System Monitoring
The function you want is ReadDirectoryChangesW. A quick search for a perl wrapper yields this Win32::ReadDirectoryChanges module.
Your script would look something like this:
use Win32::ReadDirectoryChanges;
$rdc = new Win32::ReadDirectoryChanges(path => $path,
subtree => 1,
filter => $filter);
while(1) {
#results = $rdc->read_changes;
while (scalar #results) {
my ($action, $filename) = splice(#results, 0, 2);
... run script ...
}
}
You can easily achieve this in Perl using File::ChangeNotify. This module is to be found on CPAN: http://search.cpan.org/dist/File-ChangeNotify/lib/File/ChangeNotify.pm
You can run the code as a daemon or as a service, make it watch one or more directories and then automatically execute some code (or start up a script) if some condition matches.
Best of all, it's cross-platform, so should you want to switch to a Linux machine or a Mac, it would still work.
It wouldn't be too hard to put together a small C# application that uses the FileSystemWatcher class to detect files being added to a folder and then spawn the required script. It would certainly use less CPU / system resources / hard disk bandwidth than polling the folder at regular intervals.
You need to consider what is a sufficient heuristic for determining "modified".
In increasing order of cost and accuracy:
file size (file content can still be changed as long as size is maintained)
file timestamp (If you aren't running ntpd time is not monotonic)
file sha1sum (bulletproof but expensive)
I would run ntpd, and then loop over the timestamps, and then compare the checksum if the timestamp changes. This can cover a lot of ground in little time.
These methods are not appropriate for a computer security application, they are for file management on a sane system.