How do I return text from the MediaWiki SearchAfterNoDirectMatch hook? - hook

I am trying to write a MediaWiki Search Hook that will list native files in the file system and then, eventually, allow a person to click on one of the files and view its content.
My extensions.json contains this:
"Hooks": {
"SearchAfterNoDirectMatch": "MediaWiki\\Extension\\NativeFileList\\Hooks::onSearchAfterNoDirectMatch"
},
My Hooks::onSearchAfterNoDirectMatch file looks like this:
namespace MediaWiki\Extension\NativeFileList;
class Hooks {
/**
* #see https://www.mediawiki.org/wiki/Manual:Hooks/SearchAfterNoDirectMatch
* #called from https://gerrit.wikimedia.org/g/mediawiki/core/+/master/includes/search/SearchNearMatcher.php
* #param $searchterm
* #param $title - array of titles
* Returns true if it found something, false is otherwise
*/
public static function onSearchAfterNoDirectMatch( $searchterm, &$title ) {
$title=Title::newFromText( "test", "bar");
return false;
}
}
My problem is that no text is returned. Well, it's worse than that. With the above code, I get an exception (but I don't know how to debug it, because I can't see the exception). If I take the line setting $title out, it returns. If i change the line to $title=undefined(); I get another error. If I set $title="foo"; I get no error, but no foo.
So how do I return a search hit or, even better, a set of search hits?
None of the existing search plug-ins use the modern search Hook api, which is documented in these locations:
https://www.mediawiki.org/wiki/Manual:Hooks/SearchAfterNoDirectMatch
https://gerrit.wikimedia.org/g/mediawiki/core/+/master/includes/search/SearchNearMatcher.php
https://doc.wikimedia.org/mediawiki-core/master/php/classSearchNearMatcher.html

That hook can't return text, you just can change the title in order to generate a match from the hook. $title has to be a Title object, if the code you posted above is the exact code you are using your exception is due to the second parameter not being one of the namespace constants like NS_MAIN

SearchAfterNoDirectMatch is used to return the title of a near-match, rather than to supplement the search results. For supplementing search results, use the onSpecialSearchResultsAppend. Here is code adds three lines to the search results:
class Hooks {
/**
* #see https://www.mediawiki.org/wiki/Manual:Hooks/SearchAfterNoDirectMatch
* #called from https://gerrit.wikimedia.org/g/mediawiki/core/+/master/includes/search/SearchNearMatcher.php
* #param $searchterm
* #param $title - array of titles
*/
public static function onSpecialSearchResultsAppend( $that, $out, $term ) {
$out->addHTML("<h3>Extra Search Results:</h3>");
$out->addHTML("<ul>");
$out->addHTML("<li>Extra Result #1</li>");
$out->addHTML("<li>Extra Result #2</li>");
$out->addHTML("<li>Extra Result #3</li>");
$out->addHTML("</ul>");
}
}
}
That should be enough to get most people going.

Related

Codeigniter 4: authfilter filter must have a matching alias defined

I'm new to Codeigniter 4.
I'm developing something localy (Win10/XAMPP) and everything works fine. I uploaded code to linux hosting and suddenly I got error: authfilter filter must have a matching alias defined. 'authfilter' was an allias name in Config/Filters file. Than I noticed that allias is lowercased filter class name, so I changed allias to authfil and now I am getting error: Class 'App\Filters\AuthFilter' not found (SYSTEMPATH/Filters/Filters.php at line 167).
Can anyone explain to me what makes the difference; same code, Windows vs. Linux.
My App/Config/Filters contains following code:
namespace Config;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\SecureHeaders;
use App\Filters\FilterInterface;
use App\Filters\AuthFilter;
class Filters extends BaseConfig
{
/**
* Configures aliases for Filter classes to
* make reading things nicer and simpler.
*
* #var array
*/
public $aliases = [
'csrf' => CSRF::class,
'toolbar' => DebugToolbar::class,
'honeypot' => Honeypot::class,
'invalidchars' => InvalidChars::class,
'secureheaders' => SecureHeaders::class,
'authfil' => \App\Filters\AuthFilter::class,
];
/**
* List of filter aliases that are always
* applied before and after every request.
*
* #var array
*/
public $globals = [
'before' => [
// 'honeypot',
// 'csrf',
// 'invalidchars',
'authfil' ///=> ['except' => 'auth/login']
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
];
My routes looks like:
$routes->group('auth', ['filter' => 'authfil'],['namespace' => 'IonAuth\Controllers'], function ($routes) {
$routes->get('/', 'Auth::index');
$routes->add('login', 'Auth::login');
$routes->get('logout', 'Auth::logout');
...
}
Thanx in advance,
Siniša
P.S. I put: use App\Filters\AuthFilter to SYSTEMPATH/Filters/Filters.php but with no success. I also tried to add filter to the route, and all combinations that I can think of before I post the question.
The fact is, my project is quite large and today, after few months of working, I find out that I should use filters for login check instead of put login check inside initController function... InitController function is a strange approach to me, instead of using standard OOP concepts (constructors). However, there is a reason for everything, even if it's not obvious to me :).

Get JSDoc comments Node js

I use PHP's reflectionclass to write my own API documentation generator where it generates Documentation for some functions and classes by getting the Doc Comments attached to them and parsing it.
Now I need to do the same in Node.js. Is there a built-in JavaScript function that can find JSDoc comments of a specific identifier? I mean without having to write code to manually parse the source code as in this JSDoc regex question asked earlier
I need something just like in this PHP example
<?php
/**
* A test class
*
* #param foo bar
* #return baz
*/
class TestClass { }
$rc = new ReflectionClass('TestClass');
var_dump($rc->getDocComment())
?>
Output:
string(55) "/**
* A test class
*
* #param foo bar
* #return baz
*/"

Find a div in a block render in Symfony

I am doing a site with symfony 4. I start on this framework and I have a problem of design on my site.
I've been looking for where it might come from, but I can not find the code I'd like to remove.
The part of the code I would like to remove is the following because the result is pretty ugly:
I can not find this in my code:
in my controller :
/**
* #return Response
*/
public function newLetterAction(Request $request): Response
{
$form = $this->createForm(CustomerNewsletterType::class, new Customer());
$form->handleRequest($request);
$facebook = $this->manager->getRepository(ExternalUrl::class)->findOneByCode('facebook');
$instagram = $this->manager->getRepository(ExternalUrl::class)->findOneByCode('instagram');
return $this->templatingEngine->renderResponse('#SyliusShop/Homepage/_newsletter.html.twig', [
'facebook' => $facebook,
'instagram' => $instagram,
'form' => $form->createView(),
'rova_refonte' => (in_array($this->container->get('request_stack')->getMasterRequest()->attributes->get('_route'),["sylius_shop_homepage"]) ? true : false)
]);
}
in my formType :
class CustomerNewsletterType extends AbstractResourceType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class, [
'label' => 'app.ui.newsletter',
'attr' => [
'placeholder' => 'app.ui.email'
]
])
;
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix(): string
{
return 'app_customer_newsletter';
}
}
in my twig:
{{ render(controller('app.controller.shop_homepage:newLetterAction')) }}
if anyone could tell me how to find the code, it would help me a lot.
Thank you
Everything is done under the hood when you call $form->createView().
To sum up, every type of field into the form has a base rendering using twig blocks (so does the form itself), which can be overriden. This is what is called the form theme, there's a base one which is usually this one in the twig-bridge.
You can create new themes, extend the existing one, or event create just what you need for a specific form (hint : the getBlockPrefix function in your form type is used for this).
You can find all the documentation about the form rendering here :
https://symfony.com/doc/current/form/form_customization.html
Most functions described in this documentation are in fact calling twig blocks of form themes, and you can find the documentation about this here :
https://symfony.com/doc/current/form/form_themes.html
Keep in mind: Removing such a class / div might break existing CSS, error rendering or everything done in javascript targeting this class.
Most likely you use a bootstrap 3/4 form theme and there works standard form_row template layout.
To customize current form/another form elements, use "How to Work with Form Themes" tutorial.

Can an object tell Twig not to escape output when it is {{ printed }}

I've got a situation where some variables sent to my Twig templates are plain old variables, so I want them to be html-escaped (as is the default behaviour). But other variables sent to my templates are really objects with __toString() renderers... and some of these objects send out raw HTML (e.g. from a WYSIWYG editor like TinyMCE or CKEditor).
Ideally I'd like for my template designers to not have to use the |raw filter on the objects, but instead somehow have the objects tell Twig that they're already escaped.
In other words, I'm trying to mimc the behavior of a Twig function that sets is_safe, but without requiring template designers to use a function.
E.g. I could write a Twig function using the is_safe parameter in its definition and be able to have this in my templates:
{{ figure_out_what_to_do(something) }}
(where the figure_out_what_to_do knows to inspect the "something" object to ascertain whether or not it needs to be escaped). BUT to me this is no better than having to remember to put |raw after every output of "something". So instead I'd like to be able to do this:
{{ something }}
...and have Twig recognize that something is an object and hence ask it whether or not it needs to be escaped.
I'm guessing the answer is "no", but figured I'd ask in case someone who knows more about Twig internals has any pointers for me.
Thanks.
In the __toString() method you could instead of return the html output, do this : return new Twig_Markup($html, 'UTF-8'); thus marking it as a safe and not to be escaped
Instead of returning a new \Twig_Markup object in __toString() (which causes a fatal error since it must return a string) you could extend \Twig_Markup:
class Something extends \Twig_Markup {
public function __toString() {
return $this->safeValue;
}
public function count() {
return mb_strlen($this->safeValue);
}
}
Twig looks at the object to see if it is an instance of \Twig_Markup when deciding to escape the string or not. Here’s the source for \Twig_Markup:
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Twig;
/**
* Marks a content as safe.
*
* #author Fabien Potencier <fabien#symfony.com>
*/
class Markup implements \Countable
{
protected $content;
protected $charset;
public function __construct($content, $charset)
{
$this->content = (string) $content;
$this->charset = $charset;
}
public function __toString()
{
return $this->content;
}
public function count()
{
return \function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : \strlen($this->content);
}
}
class_alias('Twig\Markup', 'Twig_Markup');
As you can see in the source code, \Twig_Markup implements \Countable. That’s why I’ve overridden the implementation of public function count() in my example.

symfony #Security annotations replacing each other instead of adding to each other

In Symfony2, I really like the #Security annotation to perform permissions checks.
However, when using this annotation, I come over a limitation which is you can't cumulate them.
/**
* #Security("is_granted('organizer')")
* #Security("is_granted('owner')")
*/
public function displayPlanningsAction($isModel = false)
{
or
* #Security("is_granted('subscription_valid')")
*/
class PlanningController extends CustomBaseController
{
/**
* #Security("is_granted('owner')")
*/
public function displayPlanningsAction($isModel = false)
{
the two previous will only check for is_granted('owner'). That's kind of ok in the first example because I can just put an 'and' and write this in a single line, but it's really annoying for the second example because then I have to repeat for every method of the class.
Is there a simple way I could overcome this (without using the jmsextrasecuritybundle) ?

Resources