I am learning Mediawiki and looking at some of the extensions.
Manual:$wgUser on mediawiki.org states the global variable $wgUser should not be used for new code.
Manual:RequestContext.php says the context object should be used instead, by using either $this->getUser() or $context->getUser().
However, when I try to use $this->getUser()->getName() in the extension for Who's Online I get the following error:
Fatal error: Using $this when not in object context in /home/ghsfhaco/public_html/wiki/extensions/WhosOnline/WhosOnlineHooks.php on line 19
And when I change it to $context->getUser()->getName() I get this error:
Fatal error: Call to a member function getUser() on null in /home/ghsfhaco/public_html/wiki/extensions/WhosOnline/WhosOnlineHooks.php on line 19
The full Extension:WhosOnline can be found at Mediawiki, but here's the specific page:
class WhosOnlineHooks {
// update online data
public static function onBeforePageDisplay() {
global $wgUser;
// write to DB (use master)
$dbw = wfGetDB( DB_MASTER );
$now = gmdate( 'YmdHis', time() );
// row to insert to table
$row = array(
'userid' => $wgUser->getId(),
'username' => $wgUser->getName(),
'timestamp' => $now
);
$method = __METHOD__;
$dbw->onTransactionIdle( function() use ( $dbw, $method, $row ) {
$dbw->upsert(
'online',
$row,
array( array( 'userid', 'username' ) ),
array( 'timestamp' => $row['timestamp'] ),
$method
);
} );
return true;
}
public static function onLoadExtensionSchemaUpdates( $updater ) {
$updater->addExtensionUpdate( array( 'addTable', 'online',
__DIR__ . '/whosonline.sql', true ) );
return true;
}
}
How exactly should it be done?
BTW, I'm using Mediawiki 1.28.0.
From the page you linked (Working with Request Contexts > When using hooks): If your hook provides an OutputPage as an argument make use of the context provided by it. BeforePageDisplay does provide an OutputPage, so just use its getUser() method.
Related
I have a main plugin and a sub-plugin. The function of the sub-plugin is to extract information from a 3rd-party plugin and pass it to the main plugin.
Extracting the information is no problem, and I can pass hardcoded information through a filter.
But when I try to make the filter dynamic, it stops functioning.
What's the best approch for this situation?
Main plugin uses this code:
namespace Essif\Testing
class Hooks extends Flow
public static function options(): array {
$res = apply_filters('custom_filter_testing', '');
return $res;
}
My subplugin looks like this:
public function getTarget() {
return ['foo' => 'foo', 'bar' => 'bar'];
}
public function essif_hook_data()
{
$context = ['CF7' => 'CF7'];
$target = ['foo' => 'foo', 'bar' => 'bar'];
//$target = $this->getTarget();
$res = ['context' => $context, 'target' => $target];
return $res;
}
Using hardcoded info, it works. But if I use $this->getTarget(), it throws an error.
EDIT:
Errors:
ManageHooks::options() must be of the type array, string returned
$this
Using $this when not in object context
I looking for a function where I give a ControllerName as a param and it returns the functions in that controller. For example:
.
.
.
class ExampleController extends Controller {
public static function firstExample($param1 = ' ', $param2 = 0){
.
.
.
}
public static function secondExample($param3){
.
.
.
}
}
And if I call: $actions = MyController::getActions('ExampleController');
It outputs this structure:
array(
0 => array(
'name' => 'firstExample'
'params' => array(
0 => '$param1',
1 => '$param2',
)
),
1 => array(
'name' => 'secondExample'
'params' => array(
0 => '$param3',
)
)
);
I know how to write functions and controllers. My question is: how to get the function names and their params (and maybe their types if it's possible, too) from a different controller?
So if I understood correctly you want to get the methods of any controller, and their respective parameters.
Step 1 : Getting the methods name
Using the PHP's get_class_methods you can retrieve all the methods of a specific class.
function getActions($controllerName){
$class_methods = get_class_methods(controllerName); //getting them
foreach ($class_methods as $method_name) { //looping them
getParams($controllerName,$method_name);
}
}
Step 2 : Getting the methods parameters
Using PHP's ReflectionMethod class:
function getParams($controllerName,$method_name){
$method = new ReflectionMethod($className, $methodName);
$params = $method->getParameters();
foreach ($params as $param) {
echo $param->getName(); //add to array here
}
}
Now for getting the type, not sure if $param->getType() works, but it's just a matter of trying, anyway this is just the basic stuff, now you can manipulate the function to fit your needs.
Note: Not sure if there's a better way that comes with Laravel, this is a vanilla PHP way of doing it.
Best Regards.
I'm actually working on a Helper for CakePHP3 that include BsHelper and then the BsFormHelper.
Actually everything looks good, no problem with Bootstrap formats.
I try now to create a ckEditor instance, but I meet some several problems.
If i try to call my ckEditor like this :
$this->BsForm->ckEditor('test')
I just have some problems because the function ckEditor is in my BsFormHelper, and load function is in BsHelper. So when i try to access private var to know if i had to load ckEditor i got that issue :
Error: Call to a member function load() on a non-object
File C:\wamp3\www\wac_lucien\BsHelpersCakePHP3\3.2\plugins\BsHelpers\src\View\Helper\BsFormHelper.php
So in fact I know where is the issue :
In BsFormHelper my fonction looks like :
public function ckEditor($fieldName, $options = array(), $ckEditorOptions = array()) {
$options['type'] = 'textarea';
$out = $this->input($fieldName, $options);
// If there is a point in the fieldName
if (strpos($fieldName, '.') !== false) {
$nameForReplace = Inflector::camelize(Inflector::slug($fieldName));
} else {
$nameForReplace = $this->_modelForm . Inflector::camelize($fieldName);
}
$this->Bs->load('ckeditor');
$this->Bs->loadJS('CKEDITOR.replace("' . $nameForReplace . '", ' . json_encode($ckEditorOptions) . ');', true);
return $out;
}
And in my BsHelper i got :
public function load($key) {
if (!$this->__extensions[$key]['loaded']) {
foreach ($this->__extensions[$key]['css'] as $css) {
$this->loadCSS($css);
}
foreach ($this->__extensions[$key]['js'] as $js) {
$this->loadJS($js);
}
$this->__extensions[$key]['loaded'] = true;
}
return $this->__extensions[$key]['loaded'];
}
Values are in declaration like this
public $__extensions = array(
'jasny' => array(
'css' => array(
'//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/css/jasny-bootstrap.min.css'
),
'js' => array(
'//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js'
),
'loaded' => true
),
'ckeditor' => array(
'css' => array(),
'js' => array(
'//cdn.ckeditor.com/4.5.8/standard/ckeditor.js'
),
'loaded' => true
)
);
Can someone help me to find out ? It looks like load function called in BsFormHelper can't access privates vars from BsHelper ...
seems you are just trying to use a helper in another helper
The manual says
You may wish to use some functionality already existing in another
helper. To do so, you can specify helpers you wish to use with a
$helpers array, formatted just as you would in a controller:
So in your BsFormHelper just do
public $helpers = ['Bs'];
and you're done
( ! ) Fatal error: require(): Failed opening required '' /mvc_controller.php on line 265
I get this above error despite trying so many suggestions in the forums, stackexchange etc.
I am developing a plugin in WordPress 4.0.1 using WP MVC, and it also encapsulates ORM concept that is in-built with WP MVC. I couldnt find a solution for this.
Below is the code:
(Public Controller)
/app/controllers/geozone_rules_controller.php
<?php
class GeozoneRulesController extends MvcPublicController {
var $after = array('set_geozonerules');
public function set_geozonerules() {
$this->load_model('GeozoneRule');
$geozonerules = $this->GeozoneRule->find();
$this->set('geozonerules', $geozonerules);
}
// Overwrite the default index() method to include the 'is_public' => true condition
public function index() {
$objects = $this->GeozoneRule->find(array(
'joins' => array('Geozone', 'Country', 'Zone'),
'includes' => array('Geozone', 'Country', 'Zone'),
'selects' => array('Geozone.id, Geozone.geozone_name',
array('Country.id, Country.country_name',
array('Zone.id', 'Zone.zone_name',
array('GeozoneRule.id', 'GeozoneRule.ordering')
)
)))
);
$this->set('objects', $objects);
// pagination
$this->params['page'] = empty($this->params['page']) ? 1 : $this->params['page'];
$this->params['conditions'] = array('is_public' => true);
$collection = $this->model->paginate($this->params);
$this->set('objects', $collection['objects']);
$this->set_pagination($collection);
echo 'Add New Geozone Rule';
}
// GeozoneRule selects only GeozoneRule names and ids by default; to select all fields from GeozoneRule,
// we'll overwrite the default show() method
public function show() {
$object = $this->model->find_by_id($this->params['id'], array(
'includes' => array(
'Geozone',
'Country',
'Zone',
'GeozoneRule' => array(
'selects' => 'GeozoneRule.*'
)
)
));
if (!empty($object)) {
$this->set('object', $object);
$this->render_view('show', array('layout' => 'public'));
}
}
}
?>
Model:
<?php
class GeozoneRule extends MvcModel {
var $table = '{prefix}w2store_geozonerules';
var $primary_key = 'id';
var $display_field = 'id';
var $default_order = 'sort_name';
var $includes = array('Geozone', 'Country', 'Zone');
var $has_and_belongs_to_many = array(
'GeozoneRule' => array(
'join_table' => array('{prefix}w2store_geozones',
'fields' => array('id', 'geozone_name')),
array('{prefix}w2store_countries',
'fields' => array('id', 'country_name')),
array('{prefix}w2store_zones',
'fields' => array('id', 'zone_name')),
'fields' => array('id', 'ordering')
)
);
public function after_find($object) {
if (isset($object->geozonerules)) {
$geozonerule_names = array();
foreach($object->geozonerules as $geozonerule) {
$geozonerule_names[] = $geozonerule->name;
}
}
// print_r ($object);
// exit;
}
public function after_save($object) {
$this->update_sort_name($object);
}
public function update_sort_name($object) {
$sort_name = $object->geozonerule_name;
$this->update($object->__id, array('sort_name' => $sort_name));
}
}
?>
and now the error i got:
Warning: require(): Filename cannot be empty in /mvc_controller.php
on line 265 Call Stack
Time Memory Function Location . . 11 0.0659 3870616
Any possible solutions will be of much help. Thanks a lot.
Issue solved. Simple error made a lot of fuss.
In views/admin/ folder, there is a folder for the model GeozoneRule in the name 'geozonerules' and it was renamed to 'geozone_rules'. Now it is ok.
Naming of folders and files needs careful attention.
Thanks folks.
I am using a Remember Me Component. Actually, migrating a CakePHP 1.3 app to CakePHP 2x. I am stuck with this LAST PIECE of code that is RememberMeComponent.
The script which I see here to SET the cookie is :
function make( ) {
$data = array(
$this->ident_field => $this->_create_token( ),
$this->token_field => $this->_create_token( ),
);
$this->Cookie->name = $this->cookie_name;
$this->Cookie->time = $this->period;
$this->Cookie->key = base64url_encode(implode('::', $data));
$this->Cookie->secure = true;
$this->Auth->getModel()->save(array($this->Auth->userModel => array_merge(array('id' => $this->Auth->user('id')), $data)), false);
}
and checks with :
function check( ) {
$cookie = $this->Cookie->read($this->cookie_name);
if (empty($cookie)) {
return false;
}
$data = explode('::', base64url_decode($cookie));
$user = $this->Auth->getModel( )->find('first', array(
'conditions' => array(
$this->Auth->userModel.'.ident' => $data[0],
),
));
if ( ! $user) {
return false;
}
function base64url_encode is defined in bootstrap - so, it is valid function.
Now there is line:
$this->Auth->getModel()->save(array($this->Auth->userModel => array_merge(array('id' => $this->Auth->user('id')), $data)), false);
That is giving me an error:
Error: Call to undefined method AuthComponent::getModel()
File: /var/www/FlintStones/Controller/Component/RememberMeComponent.php
I checked Auth Component documentation but, it did not have any option where I could find the model for auth.
Thanks in advance.
PS: We cannot directly move to Auto Login (as you might have that in mind) or if you can also refer to a quick-step-by-step, please share. I might even consider that but, so far it is just to get the Auth model.
I had the same issue in the same component.
How to get $settings data out of CakePHP 2.0 FormAuthenticate object
Summary:
Use $this->Auth->userModel to get the model. If the value is null, it will default to 'User'.