Extend symfony task in plugin - plugins

I am working with a plugin in symfony 1.4, and would like to add a listener for a task from another plugin. When the user does php symfony doctrine:build I want my plugin to run a task of its own. Where/how do I register the listener? I did not have any success with http://www.symfony-project.org/gentle-introduction/1_4/en/17-Extending-Symfony
Thank you!

Actually you can hook your code to any symfony task. Have a look at sfBaseTask::doRun method. Any task, when is executed, emits 2 events: command.pre_command and command.post_command.
Create a class to store you code, for example:
class toolkitEvents
{
static public function commandPostEventHook(sfEvent $event)
{
$task = $event->getSubject();
if ($task->getFullName() === 'doctrine:build')
{
//do stuff or call another task
}
}
and connect this method to a dispatcher when initializing your plugin:
class yourPluginConfiguration extends sfPluginConfiguration
{
public function initialize()
{
$this->dispatcher->connect('command.post_command', array('toolkitEvents', 'commandPostEventHook'));
}

I don't think there is a suitable event for this (like the cache clear one).
My suggestion would be either to accept that it needs to be two tasks, or if you use build that often, create a wrapper task to call one first then the other - doctrine:build is a good example of how to do this. Or a bash/batch script!

Related

How to write the test method for the following code?

I have code for this before update trigger and I have to write the test method for it. I am completely new to apex and this is the first trigger I wrote but not getting how to write test method for it.
Code
The screenshot doesn't provide much of the details, but I am writing the test class based on the info you have shared.
Tweak the code based on how you have implemented the trigger.
#isTest
private class StatusCloseDateTest {
#isTest static void testStatusCloseDate() {
yourObjAPIName__c rectoupdate = new yourObjAPIName__c();
rectoupdate.name = 'testValue';
/* based on the type of trigger (insert,update,delete) you wrote
perform the dml action.
EG:insert rectoupdate/update rectoupdate/delete rectoupdate
*/
insert rectoupdate;
/* when you perform this dml operation, the trigger will get
invoked and the code you have written in the trigger will
be covered by this test class method.
*/
}
}
Run the test methods in this class.
In the Developer Console, click Test | New Run.
Under Test Classes, click "StatusCloseDateTest".
To add all the test methods in the "StatusCloseDateTest" class to the test run, click Add Selected.
Click Run.
For more details refer : Trailhead

Custom moodle completion rule does not work

I am developing a mod_plugin for Moodle and want to support the automatic activity completion with a custom rule. I followed the official documentation and implemented all necessary functions. In the lib.php [pluginname]_supports method I have registered, FEATURE_GRADE_HAS_GRADE, FEATURE_COMPLETION_TRACKS_VIEWS, FEATURE_COMPLETION_HAS_RULES.
The \mod_[pluginname]\completion\custom_completion class defines a custom rule named "completiontest" in get_defined_custom_rules(). During my tests I found out that the methods get_state(), get_sort_order() and get_custom_rule_descriptions() are never executed. Also I don't see any output via activity_information().
I have cleared all caches, created new instances of my activity module, with no result. My development environment uses Moodle 3.11.7 (Build: 20220509).
My custom_completion.php script:
<?php
declare(strict_types=1);
namespace mod_cwr\completion;
use core_completion\activity_custom_completion;
class custom_completion extends activity_custom_completion {
public function get_state(string $rule): int {
return COMPLETION_INCOMPLETE;
}
public static function get_defined_custom_rules(): array {
return [
'completiontest'
];
}
public function get_custom_rule_descriptions(): array {
return [
'completiontest' => 'testout'
];
}
public function get_sort_order(): array {
return [
'completionview',
'completiontest',
'completionusegrade'
];
}
}
Test at the view.php:
$completion = new completion_info($course);
$completion->set_module_viewed($coursemodule);
if($completion->is_enabled($coursemodule) == COMPLETION_TRACKING_AUTOMATIC){
$completion->update_state($coursemodule, COMPLETION_INCOMPLETE, $USER->id);
}
$completiondetails = \core_completion\cm_completion_details::get_instance($coursemodule, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($coursemodule, $USER->id);
echo $OUTPUT->activity_information($coursemodule, $completiondetails, $activitydates);
At the mod_form.php I check with completion_rule_enabled() if a custom rule is activated by the settings.
Does anyone have any idea what the problem could be?
Looking at the mod_forum plugin code showed me, that the get_state($rule) method does not observe all custom rules, only those selected in the settings. How do I tell Moodle to use a specific custom rule?
You appear to be calling update_state() and passing in the possible state change as COMPLETION_INCOMPLETE.
This is a way of telling Moodle "if the state is already incomplete, don't bother doing any expensive completion calculations to check if it should change state".
If you want Moodle to check and then (potentially) change the state to "complete", then pass COMPLETION_COMPLETE. If you really don't know which way it could be switching, then leave the param at the default COMPLETION_UNKNOWN (a good example would be forum completion - if you have just created a forum post, then you might cause the forum to be marked as "complete", but you certainly can't cause the forum to be marked as "incomplete", so you can pass the COMPLETION_COMPLETE parameter, so Moodle knows it only needs to check for changes if the forum is not already "complete").
Also, don't bother passing $USER->id as the third parameter - that's the default which is used of you don't pass anything.
As for telling Moodle which rules to use - it is up to you, when your function is called, to check your plugins settings to determine which rules are in use (and any other relevant configuration - e.g. with mod_forum, it needs to check how many posts are required for completion).
Thank you for the support. Got it running.
I now use $completion->update_state($coursemodule, COMPLETION_COMPLETE); and also had to fix [pluginname]_get_coursemodule_info() with $result->customdata['customcompletionrules']['completiontest'] = $cwr->completiontest; and totally forgot the return $result;.

removeAll() from repository in scheduler task

For my scheduler task, I want to delete all the existing data from repository before updating it, every time the scheduler runs. I am able to save and add new data from XML File using add().
class FunctionFetcherService {
public function fetchRoomandLesson() {
$path = 'http:abc.dll?type=room&content=xml';
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$roomRepository = $objectManager->get("School\\booking\\Domain\\Repository\\RoomsRepository");
$this->roomRepository->removeAll();
$xml = simplexml_load_file($path);
$json = json_encode($xml);
$xmlArray = json_decode($json, true);
$serialized_array = serialize($xmlArray);
$unserialized_array = unserialize($serialized_array);
An error occurs removeAll() called on Null. I also referred to the already asked question: use removeAll() in scheduler task but it does doe not work.
You create the repository as variable $roomRepository and then try to access it through $this->roomRepository. Changing $this->roomRepository to $roomRepository should fix the error.
You should create an Extbase CommandController as your scheduler task. All registered commands are available in the scheduler as well as CLI commands.
By using CommandControllers you can use the full extbase framework, such as dependency injections and validations.
Please note that CommandController command methods must be suffixed with Command just like the linked example.

How to run code before/after cucumber suite?

I'm trying to figure out how to run some code before and after all my cucumber tests run.
I've been tracking down a bug for a few days where some our processes create jobs on a server, and don't properly clean it up. It's easy to miss so ideally I don't want engineers to have to manually add a check to every test.
I was hoping there'd be a way to put a hook in before any tests ran to cache how many jobs exist on the server, then a hook at the end to ensure that the value hasn't changed.
I know this isn't really the best way to use cucumber, as that is more of a system test type thing to do, but doing it this way would be the best way to fit it into the existing infrastructure.
Use #BeforeClass and #AfterClass annotations in your run file.
#RunWith(Cucumber.class)
#Cucumber.Options(
format = {"json", "<the report file>"},
features = {"<the feature file>"},
strict = false,
glue = {"<package with steps classes>"})
public class TestRunFile {
#BeforeClass
public static void getJobNumbersOnServerBeforeStarting() {
//Implement logic
}
#AfterClass
public static void getJobNumbersOnServerAfterCompletion() {
//Implement logic
}
}
How about using tagged hooks.
#Before("#jobCheck")
public void beforeScenario() {
// actions
}
#After("#jobCheck")
public void afterScenario() {
// actions
}
And then for each scenario that requires this check, add #jobCheck before the Scenario definition as below.
Feature: Some feature description
#jobCheck
Scenario: It should process a sentence
// The steps
More on JVM hooks here: https://zsoltfabok.com/blog/2012/09/cucumber-jvm-hooks/

Eclipse RCP: How to access internal classes of plugins?

I want to use the default XML editor (org.eclipse.wst.xml.ui) of Eclipse in an RCP application. I need to read the DOM of the xml file currently open. The plugin doesn't offer any extension point, so I'm trying to access the internal classes. I am aware that the I should not access the internal classes, but I don't have another option.
My approach is to create a fragment and an extension point to be able to read data from the plugin. I'm trying not to recompile the plugin, that's why I thought that a fragment was necessary. I just want to load it and extract the data at runtime.
So, my question is: is there another way to access the classes of a plugin? if yes, how?
Any tutorial, doc page or useful link for any of the methods is welcome.
Since nobody answered my question and I found the answer after long searches, I will post the answer for others to use if they bump into this problem.
To access a plugin at runtime you must create and extension point and an extension attached to it into the plugin that you are trying to access.
Adding classes to a plugin using a fragment is not recommended if you want to access those classes from outside of the plugin.
So, the best solution for this is to get the plugin source from the CVS Repository and make the modifications directly into the source of the plugin. Add extension points, extensions and the code for functionality.
Tutorials:
Getting the plugin from the CVS Repository:
http://www.eclipse.org/webtools/community/tutorials/DevelopingWTP/DevelopingWTP.html
Creating extensions and extension points and accessing them:
http://www.vogella.de/articles/EclipseExtensionPoint/article.html
http://www.eclipsezone.com/eclipse/forums/t97608.rhtml
I ended up extending XMLMultiPageEditorPart like this:
public class MultiPageEditor extends XMLMultiPageEditorPart implements
IResourceChangeListener {
#Override
public void resourceChanged(IResourceChangeEvent event) {
// TODO Auto-generated method stub
setActivePage(3);
}
public Document getDOM() {
int activePageIndex = getActivePage();
setActivePage(1);
StructuredTextEditor fTextEditor = (StructuredTextEditor) getSelectedPage();
IDocument document = fTextEditor.getDocumentProvider().getDocument(
fTextEditor.getEditorInput());
IStructuredModel model = StructuredModelManager.getModelManager()
.getExistingModelForRead(document);
Document modelDocument = null;
try {
if (model instanceof IDOMModel) {
// cast the structured model to a DOM Model
modelDocument = (Document) (((IDOMModel) model).getDocument());
}
} finally {
if (model != null) {
model.releaseFromRead();
}
}
setActivePage(activePageIndex);
return modelDocument;
}
}
This is not a clean implementation, but it gets the job done.