1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00

Xomw: Add some implementation for XomwHooks [#632]

This commit is contained in:
gnosygnu 2020-04-29 07:32:10 -04:00
parent bd71db3ed6
commit db73b4302d
9 changed files with 1736 additions and 1308 deletions

View File

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*; package gplx.xowa.mediawiki; import gplx.*;
import gplx.core.strings.*; import gplx.core.strings.*;
public class XophpArray_ { public class XophpArray_ {
// REF.PHP:https://www.php.net/manual/en/function.array-merge.php // REF.PHP:https://www.php.net/manual/en/function.array-merge.php
@ -156,6 +156,7 @@ public class XophpArray_ {
public static boolean array_key_exists(String key, XophpArray array) {return array.Has(key);} public static boolean array_key_exists(String key, XophpArray array) {return array.Has(key);}
public static boolean array_key_exists(int key, XophpArray array) {return array.Has(Int_.To_str(key));} public static boolean array_key_exists(int key, XophpArray array) {return array.Has(Int_.To_str(key));}
public static void unset(XophpArray array, String s) {array.unset(s);}
public static void unset(XophpArray array, int i) {array.unset(i);} public static void unset(XophpArray array, int i) {array.unset(i);}
public static void unset(Ordered_hash array, Object key) { public static void unset(Ordered_hash array, Object key) {
array.Del(key); array.Del(key);
@ -171,7 +172,7 @@ public class XophpArray_ {
} }
// REF.PHP:https://www.php.net/manual/en/function.array-map.php // REF.PHP:https://www.php.net/manual/en/function.array-map.php
public static XophpArray array_map(XophpCallbackOwner callback_owner, String method, XophpArray array) { public static XophpArray array_map(XophpCallableOwner callback_owner, String method, XophpArray array) {
XophpArray rv = XophpArray.New(); XophpArray rv = XophpArray.New();
int len = array.count(); int len = array.count();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
@ -208,7 +209,7 @@ public class XophpArray_ {
public static Object array_pop(XophpArray array) {return array.pop();} public static Object array_pop(XophpArray array) {return array.pop();}
public static boolean isset(XophpArray array, int key) {return XophpObject_.isset_obj(array.Get_at(key));} public static boolean isset(XophpArray array, int key) {return XophpObject_.isset_obj(array.Get_at(key));}
public static boolean isset(XophpArray array, String key) {return XophpObject_.isset_obj(array.Get_by(key));} public static boolean isset(XophpArray array, String key) {return XophpObject_.isset_obj(array.Get_by(key));}
public static boolean is_array(XophpArray array) {return array != null;} public static boolean is_array(Object array) {return array != null;}
// REF.PHP: https://www.php.net/manual/en/function.in-array.php // REF.PHP: https://www.php.net/manual/en/function.in-array.php
public static boolean in_array(Object needle, XophpArray haystack) {return in_array(needle, haystack, false);} public static boolean in_array(Object needle, XophpArray haystack) {return in_array(needle, haystack, false);}

View File

@ -0,0 +1,10 @@
package gplx.xowa.mediawiki;
public class XophpCallable {
public XophpCallable(XophpCallableOwner owner, String methodName) {
this.owner = owner;
this.methodName = methodName;
}
public XophpCallableOwner Owner() {return owner;} private final XophpCallableOwner owner;
public String MethodName() {return methodName;} private final String methodName;
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*; package gplx.xowa.mediawiki;
public interface XophpCallbackOwner { public interface XophpCallableOwner {
Object Callback(String method, Object... args); Object Callback(String method, Object... args);
} }

View File

@ -0,0 +1,8 @@
package gplx.xowa.mediawiki;
public class XophpCallable_ {
// REF.PHP: https://www.php.net/manual/en/function.call-user-func-array.phphttps://www.php.net/manual/en/function.call-user-func-array.php
public static Object call_user_func_array(XophpCallable callback, XophpArray param_arr) {
return callback.Owner().Callback(callback.MethodName(), param_arr);
}
}

View File

@ -0,0 +1,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki;
public class XophpFatalError extends XophpError {
public XophpFatalError(String msg) {
super(msg);
}
}

View File

@ -13,13 +13,13 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*; package gplx.xowa.mediawiki; import gplx.*;
import gplx.core.btries.*; import gplx.core.btries.*;
import gplx.core.intls.*; import gplx.core.intls.*;
import gplx.objects.strings.unicodes.*; import gplx.objects.strings.unicodes.*;
import gplx.core.primitives.*; import gplx.core.primitives.*;
import gplx.objects.strings.bfrs.*; import gplx.objects.strings.bfrs.*;
public class XophpString_ implements XophpCallbackOwner { public class XophpString_ implements XophpCallableOwner {
public static final String False = null; public static final String False = null;
public static boolean is_true (String s) {return s != null;} // handles code like "if ($var)" where var is an Object; public static boolean is_true (String s) {return s != null;} // handles code like "if ($var)" where var is an Object;
public static boolean is_false(String s) {return s == null;} public static boolean is_false(String s) {return s == null;}
@ -573,5 +573,5 @@ public class XophpString_ implements XophpCallbackOwner {
throw Err_.new_unhandled_default(method); throw Err_.new_unhandled_default(method);
} }
} }
public static final XophpCallbackOwner Callback_owner = new XophpString_(); public static final XophpCallableOwner Callback_owner = new XophpString_();
} }

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,178 +13,242 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.mediawiki.includes; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; package gplx.xowa.mediawiki.includes;
/** // MW.SRC:1.33.1
* Hooks cl+ass.
* import gplx.xowa.mediawiki.*;
* Used to supersede $wgHooks, because globals are EVIL. /*
* TODO:
* @since 1.18 * $wgHooks
* array_shift
* Closure?
*/ */
/**
* Hooks class.
*
* Used to supersede $wgHooks, because globals are EVIL.
*
* @since 1.18
*/
public class XomwHooks { public class XomwHooks {
// /** /**
// * Array of events mapped to an array of callbacks to be run * Array of events mapped to an array of callbacks to be run
// * when that event is triggered. * when that event is triggered.
// */ */
// protected static $handlers = []; protected static XophpArray handlers = XophpArray.New();
//
// /** /**
// * Attach an event handler to a given hook. * Attach an event handler to a given hook.
// * *
// * @param String $name Name of hook * @param string $name Name of hook
// * @param callable $callback Callback function to attach * @param callable $callback Callback function to attach
// * *
// * @since 1.18 * @since 1.18
// */ */
// public static function register( $name, $callback ) { public static void register(String name, XophpCallable callback) {
// if ( !isset( self::$handlers[$name] ) ) { handlers.Get_by_ary(name).Add(callback);
// self::$handlers[$name] = []; }
// }
// /**
// self::$handlers[$name][] = $callback; * Clears hooks registered via Hooks::register(). Does not touch $wgHooks.
// } * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined.
// *
// /** * @param string $name The name of the hook to clear.
// * Clears hooks registered via Hooks::register(). Does not touch $wgHooks. *
// * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined. * @since 1.21
// * * @throws MWException If not in testing mode.
// * @param String $name The name of the hook to clear. * @codeCoverageIgnore
// * */
// * @since 1.21 public static void clear(String name) {
// * @throws MWException If not in testing mode. // if (!defined('MW_PHPUNIT_TEST') && !defined('MW_PARSER_TEST')) {
// */ // throw new MWException('Cannot reset hooks in operation.');
// public static function clear( $name ) { // }
// if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
// throw new MWException( 'Cannot reset hooks in operation.' ); XophpArray_.unset(handlers, name);
// } }
//
// unset( self::$handlers[$name] ); /**
// } * Returns true if a hook has a function registered to it.
// * The function may have been registered either via Hooks::register or in $wgHooks.
// /** *
// * Returns true if a hook has a function registered to it. * @since 1.18
// * The function may have been registered either via Hooks::register or in $wgHooks. *
// * * @param string $name Name of hook
// * @since 1.18 * @return bool True if the hook has a function registered to it
// * */
// * @param String $name Name of hook public static boolean isRegistered(String name) {
// * @return boolean True if the hook has a function registered to it // global $wgHooks;
// */ // return !XophpArray_.empty($wgHooks[$name]) || !XophpArray_.empty(handlers[$name]);
// public static function isRegistered( $name ) { return false;
// global $wgHooks; }
// return !empty( $wgHooks[$name] ) || !empty( self::$handlers[$name] );
// } /**
// * Returns an array of all the event functions attached to a hook
// /** * This combines functions registered via Hooks::register and with $wgHooks.
// * Returns an array of all the event functions attached to a hook *
// * This combines functions registered via Hooks::register and with $wgHooks. * @since 1.18
// * *
// * @since 1.18 * @param string $name Name of the hook
// * * @return array
// * @param String $name Name of the hook */
// * @return array public static XophpArray getHandlers(String name) {
// */ // global $wgHooks;
// public static function getHandlers( $name ) {
// global $wgHooks; if (!isRegistered(name)) {
// return XophpArray.New();
// if ( !self::isRegistered( $name ) ) { // } else if (!XophpArray_.isset(handlers, name)) {
// return []; // return $wgHooks[name];
// } elseif ( !isset( self::$handlers[$name] ) ) { // } else if (!isset($wgHooks[name])) {
// return $wgHooks[$name]; // return handlers[name];
// } elseif ( !isset( $wgHooks[$name] ) ) { } else {
// return self::$handlers[$name]; // return XophpArray_.array_merge(handlers.Get_by_ary(name), $wgHooks[name]);
// } else { return XophpArray_.array_merge(handlers.Get_by_ary(name));
// return array_merge( self::$handlers[$name], $wgHooks[$name] ); }
// } }
// }
// /**
// /** * @param string $event Event name
// * Call hook functions defined in Hooks::register and $wgHooks. * @param array|callable hook
// * * @param array $args Array of parameters passed to hook functions
// * For a certain hook event, fetch the array of hook events and * @param string|null $deprecatedVersion [optional]
// * process them. Determine the proper callback for each hook and * @param string &$fname [optional] Readable name of hook [returned]
// * then call the actual hook using the appropriate arguments. * @return null|string|bool
// * Finally, process the return value and return/throw accordingly. */
// * private static String callHook(String event, Object hookObj, XophpArray args) {return callHook(event, hookObj, args, null, null);}
// * @param String $event Event name private static String callHook(String event, Object hookObj, XophpArray args, String deprecatedVersion) {return callHook(event, hookObj, args, deprecatedVersion, null);}
// * @param array $args Array of parameters passed to hook functions private static String callHook(String event, Object hookObj, XophpArray args, String deprecatedVersion,
// * @param String|null $deprecatedVersion Optionally, mark hook as deprecated with version number String fname
// * @return boolean True if no handler aborted the hook ) {
// * XophpArray hook;
// * @throws Exception // Turn non-array values into an array. (Can't use casting because of objects.)
// * @throws FatalError if (!XophpArray_.is_array(hookObj)) {
// * @throws MWException hook = XophpArray.New(hookObj);
// * @since 1.22 A hook function is not required to return a value for }
// * processing to continue. Not returning a value (or explicitly else { // XO: cast it to XophpArray
// * returning null) is equivalent to returning true. hook = (XophpArray)hookObj;
// */ }
// public static function run( $event, array $args = [], $deprecatedVersion = null ) {
// foreach ( self::getHandlers( $event ) as $hook ) { // if (!array_filter(hook)) {
// // Turn non-array values into an array. (Can't use casting because of objects.) // Either array is empty or it's an array filled with null/false/empty.
// if ( !is_array( $hook ) ) { // return null;
// $hook = [ $hook ]; // }
// }
// // if (is_array(hook[0])) {
// if ( !array_filter( $hook ) ) { // First element is an array, meaning the developer intended
// // Either array is empty or it's an array filled with null/false/empty. // the first element to be a callback. Merge it in so that
// continue; // processing can be uniform.
// } elseif ( is_array( $hook[0] ) ) { // hook = array_merge(hook[0], array_slice(hook, 1));
// // First element is an array, meaning the developer intended // }
// // the first element to be a callback. Merge it in so that
// // processing can be uniform. /**
// $hook = array_merge( $hook[0], array_slice( $hook, 1 ) ); * hook can be: a function, an object, an array of $function and
// } * $data, an array of just a function, an array of object and
// * method, or an array of object, method, and data.
// /** */
// * $hook can be: a function, an Object, an array of $function and if (XophpType_.instance_of(hook.Get_at(0), XophpCallable.class)) { // XophpClosure
// * $data, an array of just a function, an array of Object and // $fname = "hook-" + event + "-closure";
// * method, or an array of Object, method, and data. // $callback = array_shift(hook);
// */ } else if (XophpObject_.is_object(hook.Get_at_str(0))) {
// if ( $hook[0] instanceof Closure ) { // Object object = XophpArray_.array_shift(hook);
// $func = "hook-$event-closure"; // Object method = XophpArray_.array_shift(hook);
// $callback = array_shift( $hook );
// } elseif ( is_object( $hook[0] ) ) { // If no method was specified, default to on$event.
// $Object = array_shift( $hook ); // if ($method === null) {
// $method = array_shift( $hook ); // $method = "on" + event;
// // }
// // If no method was specified, default to on$event.
// if ( $method === null ) { // $fname = get_class($object) . '::' . $method;
// $method = "on$event"; // $callback = [ $object, $method ];
// } // } else if (is_string(hook[0])) {
// // $fname = $callback = array_shift(hook);
// $func = get_class( $Object ) . '::' . $method; // } else {
// $callback = [ $Object, $method ]; // throw new MWException('Unknown datatype in hooks for ' . $event . "\n");
// } elseif ( is_string( $hook[0] ) ) { }
// $func = $callback = array_shift( $hook );
// } else { // Run autoloader (workaround for call_user_func_array bug)
// throw new MWException( 'Unknown datatype in hooks for ' . $event . "\n" ); // and throw error if not callable.
// } // if (!is_callable($callback)) {
// // throw new MWException('Invalid callback ' . $fname . ' in hooks for ' . $event . "\n");
// // Run autoloader (workaround for call_user_func_array bug) // }
// // and throw error if not callable.
// if ( !is_callable( $callback ) ) { // mark hook as deprecated, if deprecation version is specified
// throw new MWException( 'Invalid callback ' . $func . ' in hooks for ' . $event . "\n" ); if (deprecatedVersion != null) {
// } // wfDeprecated("$event hook (used in $fname)", deprecatedVersion);
// }
// // mark hook as deprecated, if deprecation version is specified
// if ( $deprecatedVersion !== null ) { XophpCallable callback = null;
// wfDeprecated( "$event hook (used in $func)", $deprecatedVersion );
// } // Call the hook.
// XophpArray hook_args = XophpArray_.array_merge(hook, args);
// // Call the hook. return (String)XophpCallable_.call_user_func_array(callback, hook_args);
// $hook_args = array_merge( $hook, $args ); }
// $retval = call_user_func_array( $callback, $hook_args ); /**
// * Call hook functions defined in Hooks::register and $wgHooks.
// // Process the return value. *
// if ( is_string( $retval ) ) { * For the given hook event, fetch the array of hook events and
// // String returned means error. * process them. Determine the proper callback for each hook and
// throw new FatalError( $retval ); * then call the actual hook using the appropriate arguments.
// } elseif ( $retval === false ) { * Finally, process the return value and return/throw accordingly.
// // False was returned. Stop processing, but no error. *
// return false; * For hook event that are not abortable through a handler's return value,
// } * use runWithoutAbort() instead.
// } *
// * @param string $event Event name
// return true; * @param array $args Array of parameters passed to hook functions
// } * @param string|null $deprecatedVersion [optional] Mark hook as deprecated with version number
* @return bool True if no handler aborted the hook
*
* @throws Exception
* @throws FatalError
* @throws MWException
* @since 1.22 A hook function is not required to return a value for
* processing to continue. Not returning a value (or explicitly
* returning null) is equivalent to returning true.
*/
public static boolean run(String event) {return run(event, XophpArray.New(), null);}
public static boolean run(String event, XophpArray args) {return run(event, args, null);}
public static boolean run(String event, XophpArray args, String deprecatedVersion) {
XophpArray handlers = getHandlers(event);
for (int i = 0; i < handlers.count(); i++) {
XophpCallable hook = (XophpCallable)handlers.Get_at(i);
Object retval = callHook(event, hook, args, deprecatedVersion);
if (retval == null) {
continue;
}
// Process the return value.
if (XophpString_.is_string(retval)) {
// String returned means error.
throw new XophpFatalError((String)retval);
} else if (XophpObject_.is_false(retval)) {
// False was returned. Stop processing, but no error.
return false;
}
}
return true;
}
// /**
// * Call hook functions defined in Hooks::register and $wgHooks.
// *
// * @param string $event Event name
// * @param array $args Array of parameters passed to hook functions
// * @param string|null $deprecatedVersion [optional] Mark hook as deprecated with version number
// * @return bool Always true
// * @throws MWException If a callback is invalid, unknown
// * @throws UnexpectedValueException If a callback returns an abort value.
// * @since 1.30
// */
// public static function runWithoutAbort($event, array $args = [], $deprecatedVersion = null) {
// foreach (getHandlers($event) as hook) {
// $fname = null;
// retval = callHook($event, hook, $args, $deprecatedVersion, $fname);
// if (retval !== null && retval !== true) {
// throw new UnexpectedValueException("Invalid return from $fname for unabortable $event.");
// }
// }
// return true;
// }
} }

View File

@ -4563,13 +4563,12 @@ Tfds.Write(nowiki, isHTML, forceRawInterwiki, isChildObj, isLocalObj, titleText,
// Hooks::run('ParserFetchTemplate', // Hooks::run('ParserFetchTemplate',
// [ parser, title, rev, &text, &deps ]); // [ parser, title, rev, &text, &deps ]);
if (XophpString_.is_false(text) || XophpString_.is_null(text)) { if (XophpString_.is_false(text) || XophpString_.is_null(text)) {
text = XophpString_.False; text = XophpString_.False;
break; break;
} }
} else if (title.getNamespace() == XomwDefines.NS_MEDIAWIKI) { } else if (title.getNamespace() == XomwDefines.NS_MEDIAWIKI) {
// message = wfMessage(MediaWikiServices::getInstance().getContentLanguage(). // message = XomwGlobalFunctions.wfMessage(MediaWikiServices.getInstance().getContentLanguage().
// lcfirst(title.getText())).inContentLanguage(); // lcfirst(title.getText())).inContentLanguage();
// if (!message.exists()) { // if (!message.exists()) {
// text = false; // text = false;