Extension talk:PhpTags

Jump to navigation Jump to search

About this board

Johnywhy (talkcontribs)

Is there a feature to save data to a table in the database?

Reply to "Save to Database?"

file_get_contents?

6
Summary by Johnywhy

file_get_contents is not supported by PhpTags.

That woud be a security risk, because it could potentially enable web-clients to read web-server system files with passwords, and make any requests from the web-server to maybe intranet or other servers.

That would mean access to a lot of services which are normally trusted only to local connections.

But, How does it allow web-clients to make dangerous operations without password requirement? Why no password requirement?

Johnywhy (talkcontribs)

simple hello-world works fine, but file_get_contents returns

PhpTags Fatal error: Call to undefined function file_get_contents() in Draft:TestPHP on line 2

Here's the sample code:

<phptag>
$foo = 'hello world!';
echo $foo;
</phptag>

<phptag>
$searchResults = file_get_contents('https://www.nature.com/articles/s41467-018-03445-z');
echo $searchResults;
</phptag>

How to enable file_get_contents?

Pastakhov (talkcontribs)

It is not real PHP, it is just faster and powerful alternative for Help:Magic Words

And file_get_contents never should be enabled there by security reason.

Johnywhy (talkcontribs)

thx, what's the security risk?

Pastakhov (talkcontribs)

Read system files with passwords and make any requests from the server to maybe intranet or any other server including itself. A lot of services trust to local connections and allow to make dangerous operations without password requirement.

Johnywhy (talkcontribs)

How does it allow web-clients to make dangerous operations without password requirement? Why no password requirement?

Pastakhov (talkcontribs)

Sorry for the delay, I was hard busy. I meant that some services allows to make dangerous operations for clients who connected to localhost interface (127.0.0.1) because nobody can connect to localhost interface from the internet or other network. But if you provide uncontrolled access to the file_get_contents function, somebody can try to use it to hack your server.

Reply to "file_get_contents?"

Pass mediawiki template parameter to/from php?

3
Nuada99 (talkcontribs)

Is there some way to pass a mediawiki template variable to the <phptag> section of code? For that matter, is there a way to have one or more outputs of the php become the result of a template parameter?

For example:

{{Template:TestingPHP

| parameter1 = 99+21

| parameter2 = {{#phptag: $foo = {{{argument1}}}; $bar = explode("+", $foo); echo $bar[1]; }}

}}

Ideally, the value of "parameter2" would become the second element of the $bar array (21), but instead I get a php error. It doesn't seem to like the curly-braces of template parameters.

Apologies if this is a stupid question. I'm still wrapping my head around php.

Pastakhov (talkcontribs)

Hi, You going to use {{{argument1}}} as a PhpTags code, it isn't very nice idea and solution.

As a variant you may get access to argument1 by using special variable $argv for example

{{Template:TestingPHP

| parameter1 = 99+21 | parameter2 = {{#phptag: $foo = $argv['argument1']; $bar = explode("+", $foo); echo $bar[1]; }}

}}

Pastakhov (talkcontribs)
Reply to "Pass mediawiki template parameter to/from php?"
Martynov Maxim (talkcontribs)

Upgrading PHP version from 5.6 to 7.0.7 causes something wrong with comparisons.

For example, && and || operators in if block causes run of neither true block nor false, like I haven`t that IF at all.

Also there are some problems with ternary operator - sometimes it doesn`t work.

Rewriting all complex conditions with conjunction, disjunction or ternary to ( () * () != 0), ( () + () != 0) and IF operator solve an issue, and you can make your wiki much faster using PHP 7.0

Pastakhov (talkcontribs)

thanks for the report. I'll test it on PHP 7.0

Reply to "PHP 7.0"
Christharp (talkcontribs)

Hi

I wrote you previously when the extension was foxway. Anyways I was wondering how the extension, and extensions, were going? From the gist that I gather I find the notion of magic expressions to be very interesting. Wondering when you think the extension(s) will be a high enough to be production ready?

On a secondary note, I gather, or think it was implied somewhere, that this series of interconnecting extensions is looking to be a replacement, or a faster version, of semantic mediawiki? Or was my understanding flawed in some way?

All the best to you.

Pastakhov (talkcontribs)

Hi

I think "production ready" is a little vague definition :-)

I see no reason why it cannot be used in production now. Yes, there are the some lacks and most likely hidden bugs (сan be anything without them?), but generally it is ready for trying use in production.

At this moment main subquality are:

  • insufficient test coverage of exceptions
  • the pages with PhpTags errors are not placing into the category "pages with PhpTags errors"
  • inconvenient to edit the source code, I am deciding this problem with Extension:CodeMirror
  • it can be used for DDoS attacks, restriction public access to expensive functions can helps
  • not all PHP operators are implemented yet
  • almost absent PhpTags compatible extensions that really useful for end users

As you can see, it's all just a matter of time and desire to do it. Since it is a open source project, you can help develop it or just wait while others develop it :-) In any case I am open for cooperation.

The first who was going to use this extension is User:JoelKP. I helped him by writing Extension:PhpTags SMW that is used for accessing SMW data. I hope he will come back and write some review...

I do not use this extension yet, because I need a more flexible and fast alternative to semantic mediawiki and I am going to do it with PhpTags. I also have a lot of ideas related to the user interface. Of course, this requires a lot of effort to develop. I still have the desire and ability to develop it and maybe in the end it will be done.

Best of luck.

Christharp (talkcontribs)

It sounds great. Wish I could help, but limited time and a lack of trusting my coding skills at the moment is a problem.

I assume, or read somewhere, that the extension can be namespace restricted? But can it execute the code when transincluded? Currently I'm using the following extension for html: Extension:NamespaceHTML. I got the developer to change it so it can be transincluded. This way I treat the template, property (Semantic), namespaces as "developer" namespaces, which I assume I could do with PhpTags (My assumption is that end users really just want to write, upload photos,videos, etc with no html, no wiki-syntax, semantic wiki-syntax or phptags syntax. The closer to FaceBook the happier they are) This would seem to limit the possibility of DDoS attackes, but maybe I'm missing something.

Anyways best of luck to you. I'll be in touch & assuming I end up using the extension I'll throw you whatever little insides I run across.

Pastakhov (talkcontribs)

> I assume, or read somewhere, that the extension can be namespace restricted?
Yes, use variable $wgPhpTagsNamespaces, example: $wgPhpTagsNamespaces = array( NS_DEVELOPER => true ); It will allow to use PhpTags only in NS_DEVELOPER namespace.

> But can it execute the code when transincluded?
Yes of course.

> This would seem to limit the possibility of DDoS attackes...
Yes, you are right, but do not worry, I am sure PhpTags is not the weakest link. There are a lot of ways to create a critical load on the server. PhpTags can only make it a little easier for intruders.

I can help you to resolve any small task, if you would like. I will show you how it can be resolved with PhpTags.

My best wishes to you.

Christharp (talkcontribs)
Pastakhov (talkcontribs)

Yes, it does not look very optimized and I'm sure it can work only in theory.

You're right, with phptags it should be much faster.

The easiest way is using Extension:PhpTags SMW make requests to SMW and process the result using Extension:PhpTags Functions and display it using {{#rating: {{#phptag: $result}} }}.

I'll do it quickly if you give me url and access to your wiki. You should install Extension:PhpTags, Extension:PhpTags SMW, Extension:PhpTags Functions and User:Vedmaka/Semantic_Query_Interface.

Of course, ideally, it should work using only PhpTags extensions and I will strive for this, but it takes a lot of time.

Pastakhov (talkcontribs)

I looked today at this more closely and see even more simple solution:

{{#rating: {{#ask:[[Item::<q>[[Author::{{FULLPAGENAME}}]][[Category:Items]]</q>]][[Category:Reviews]]|?Rating|format=average}} }}

I could be wrong, since I can not test it.

it gives incorrect result

Christharp (talkcontribs)

Hi

Thanks for even trying. Been swamped or I would have replied sooner. I'm currently redesigning my wiki in the Foreground skin and as soon as I get it under control i"ll be trying out phptags.

All the best to you

JoelKP (talkcontribs)

> The first who was going to use this extension is User:JoelKP. I helped him by writing Extension:PhpTags SMW that is used for accessing SMW data. I hope he will come back and write some review...

Sorry for the rather late reply.

Only recently have I come to actually take the use of PhpTags further. Earlier, I came no further than testing, and then the wiki project I'm working on was put on hold for some time. Now It's been taken up again, and I'll both be using PhpTags more and doing more development of extensions.

The idea of a "more flexible and fast alternative" to Semantic MediaWiki is interesting, but I'm guessing that it will also take quite a while. Currently I'll be going along a more pragmatic short-term route getting SMW functionality as flexible as I need it with PhpTags. Best of luck with the alternative approach, and if the work I've begun turns out well, then eventually it may mean that there will be two powerful systems that can be used through PhpTags.

Regarding PhpTags SMW, the approach works well, but Semantic Query Interface (which it uses) needs some work. The basic design ideas for SQI are good, but the implementation is rough. I also want to add a second query interface class (which uses the first as a building block) for recursively following page properties and building a structure (graph representation) of the page relationships. This representation should then be simple to use through PhpTags to e.g. print a hierarchical navigation list for the pages.

SQI also contains some neat things already besides the query interface class. It can be used to set properties on pages. That function will be made accessible in the future PhpTags SMW update.

Having said all that about PhpTags SMW and SQI, here's a brief review of PhpTags itself so far:

  • It works.
  • It's simple to make an interface available through PhpTags in an extension. The amount of code needed is small.
  • While the PHP language support in PhpTags does not include defining functions, it's not too impractical to place things complex enough to need it in an extension. Such extensions could be more general, or could become a wiki-specific code library.

One example of a smaller project I might end up doing (and releasing if of general use) is to write an extension for handling sort keys for pages. PhpTags Wiki can set them, and it's easy to write functions to transform title strings for different kinds of pages.

Finally, thanks for the assistance earlier you helped get me started.

Pastakhov (talkcontribs)

Hi, Joel! Thanks for feedback :-)

Pay attention to Extension:CodeMirror. I did it for easier writing PhpTags code but I was distracted by highlighting wikitext. The idea is to make the code autocompletion, but I have not reached that goal yet. In any case, it may already be useful and interesting.

And I started experiments with Extension:PhpTags Widgets. You can see Slick.

You are welcome!

This post was hidden by Martynov Maxim (history)
Reply to "Production level"
StasR (talkcontribs)

I make a set of templates which must have error messages that include text of template call. I understand how this program, but in the absence of user-defined functions I have to make a separate template, where the original argv already unavailable. Is there a built-in function that converts an array (including non-numeric keys) to a string ?

Pastakhov (talkcontribs)

I made all native function of php in phptags functions. If there is no any needed, give me know and I make it :-). That way you may search in google 'what php function convert an array to string' and use example that you find.

You need to use function implode. I'm not sure, can it works with non-numeric keys, but you always can use function array_values and get all values of array with numeric keys only.

Reply to "argv enumeration"
Summary by Pastakhov

If you need to break PhpTags and go out, use 'break' operator:

<phptag>

if ( $foo = null ) {

break; // go out

}

echo '$foo is not null';

</phptag>

'exit' and 'return' still are not ready.

StasR (talkcontribs)

Делаю шаблон, все тело которого — один phptag. Естественное желание — не тащить исключительные ситуации через if/else до конца шаблона, а поставить вслед за echo "ошибка в параметрах" что-то вроде exit или return (меня устроит и вариант прекращения текущего phptag, и вариант завершения шаблона в целом, т. к. для меня это совпадает). Реально?

Pastakhov (talkcontribs)

точно будет работать 'break;' exit и return не реализованы. return и exit можно сделать, но пока их нет

StasR (talkcontribs)

синтаксис не приниципиален, так что break вполне устраивает, спасибо )

Pastakhov (talkcontribs)

это открытый проект? если да, то я могу смотреть время от времени, может что подскажу как лучше делать...

StasR (talkcontribs)

Спасибо огромное! Проект пока еще на локальном сервере, но как только переложу, то непременно Вашу любезность проэксплуатирую ;-)

Pastakhov (talkcontribs)

договорились )

Summary by Pastakhov

PhpTags until version 5.4.0 had a bag in array constructor.

When array created with variables inside, like $arr = array( $foo, $bar );

only last value was correct, all others was null.

This fixed in version 5.4.0

StasR (talkcontribs)

Павел, добрый день!

Что-то странное у меня получилось: пример.

Pastakhov (talkcontribs)

Да, где-то ошибка в программе. Спасибо, что нашли. Буду искать и исправлять...

Pastakhov (talkcontribs)

Исправлено в версии 5.4.0 (master)

Ошибка была в конструкторе массива, проявлялась только когда массив создавался из переменных.

Указатель не уничтожался и поэтому все время переписывался, таким образом все значения кроме последнего были null.

Clump (talkcontribs)

I am using a phptags in a template, and although no single invocation of the template iterates in loops enough to get anywhere remotely near $wgPhpTagsMaxLoops, I am reaching the limit after a few dozen invocations of the template on a large page. Is the $wgPhpTagsMaxLoops variable meant to be a limit on the total number of loop iterations allowed in rendering a page, even across distinct uses of phptags---I know $wgPhpTagsMaxLoops can be changed, but is that really the intended behaviour? (MW 1.24.1, PhpTags 4.2.0).

Reply to "$wgPhpTagsMaxLoops"

Designing APIs in PhpTags extensions: limitations and best practices

5
JoelKP (talkcontribs)

Currently I'm developing a new extension, for which, in turn, there will be an interface in the next PhpTags SMW version. This has led to some questions which I think are more general.

The new extension defines a set of classes that are used together. The first question is: should a full wrapper for this API be made for use with PhpTags, or something simpler and more limited? I don't yet know which would be best theoretically (perhaps a simpler interface makes sense anyway) but in practice, currently it would become much more complex to make a full wrapper. This leads to the second question, that of an idea for a possible PhpTags feature.

When making a PhpTags wrapper for a more complex OO API, new problems arise which the wrapper extension must deal with. What is simple when each class is used by itself requires more when classes use instances of each other. For every method which returns instances of a class, the wrapper must instead return wrapper objects. And for every method which receives instances of a class, the wrapper will receive wrapped objects and must handle these to pass on the original objects to the original API. This requires extra code, especially if arrays containing class instances are parameters and/or return values.

It would become simpler if there was a way to make PhpTags handle the wrapping and unwrapping of certain classes automatically. The idea is this: Currently, in PhpTags extensions there is a mapping between class names as used in PhpTags and the classes that implement them. I wonder, could the possibility also be added to similarly set a mapping between non-PhpTags class names and the corresponding PhpTags extension classes that wrap around them? For automatic "translation".

The idea would be that the first time a non-PhpTags object is handled in a PhpTags expression, if such a mapping exists for the class name, then PhpTags would automatically construct the wrapper object and make it usable. Then the wrapper object would be used for all access to the object's members and methods. At the same time, in such cases, the original object would still be passed around on the PHP level. So any functions or methods which receive the object as an argument would receive the original object instead of the wrapper object. (And likewise if they receive e.g. an array containing the object.)

I don't know if this would be too difficult, or cause too great a performance overhead. If not, then it could actually make for better performance for complex APIs. In the methods in a PhpTags wrapper class, there would be no need to, say, reconstruct arrays of objects to change between the original objects and wrapper objects. If the original API returns an array with original objects, then the wrapper can simply return this, instead of a new array with wrapper objects. Likewise, when the wrapper receives an array with objects, they will be the original objects instead of wrapper objects, and the array can therefore be passed directly to the original API.

Even without such a feature, simpler APIs are still easy to support in a PhpTags extension. I don't know how simple or complex the feature might turn out to be to implement, nor how generally worthwhile it would be. However, if added, I think it would make it much easier to support more complex APIs in extensions for PhpTags.

Pastakhov (talkcontribs)

Hi, Joel!

In fact, such universal wrapper is done easy, the difficulty lies in the other...

I have done PhpTagsFuncNativeObject class. It is used for wrapping DateTime, DateTimeZone, DateInterval and DatePeriod classes in the Phptags Function extension. This class has few simple methods and can be used for wrapping almost any classes. (except classes that contains dynamic methods, but it also can be done).

The PhpTags extension is designed for sandboxing PHP code and the wrappers main task is check passed parameters and control access to resources (as firewall).

Generally PHP objects that we want to use with PhpTags (for example DateTime object) cannot hurt to system and they don't need be controled. But checking passed parameters is hurt me because PHP has no needed exceptions. I tried resolve it with using function set_error_handler, but it works not very well.

Finally I decided to make a description of all functions and classes that are used in PhpTags. The description contains count and type of parameters for all functions and methods of objects, and Runtimes check it every time. It will also allow to implement autocompletion code feature in the CodeMirror extension.

I almost finished work on it. , , , .

So, the most difficult work is make the description in json file.

However, the reality is different from the desired and developers should never relax and must do more to ensure safety. For examle . It transfers unchecked parameters to new \SQI\SemanticQueryInterface object. It is potential security issue, because SemanticQueryInterface does not check them also.

As for performance, I do not worry about it so much, because any optimization or vice versa code complexity has little effect on it now.

I am open to any suggestions and discussions :-) Have a nice time!

JoelKP (talkcontribs)

Looks good, more elegant than the old approach. It seems simpler, with (nearly) all registration of classes, functions, constants, etc., unified with the argument and type check info.

The one exception seems to be constants defined through a callback, to allow the dynamically determined constants in PhpTags Wiki. I don't know how useful it would be to make dynamically generated registrations more general, but if it sounds worthwhile, the following comes to mind. Rather than having callbacks specifically for constants, there could be callbacks that fill in (either receiving and using, or constructing and returning) a general data structure, which corresponds to what is loaded from a JSON file. Then callbacks could add anything which PhpTags supports but which is not known in advance.

Thanks for the info on PhpTagsFuncNativeObject. I'm guessing that objects using it would also be described in the JSON file, though it's currently not included in the draft change you linked to for PhpTags Functions.

As for PhpTags SMW, I'll make sure parameter handling is more sane in the next version. It will use different classes, with a different design (in the process of being worked out), and checking should end up much simpler.

One comment on the PhpTagsHooks API, now that you're changing it: it may make sense to call the public "set..." methods "add..." or "register..." instead, since they do not replace anything, but instead add/register things.

Finally, I had another series of ideas in considering the new design you're describing and working on. However, these ideas only add things on top of the design, and I don't know how useful they might be. Here's a list of them in case there's something of value in it:

  • Simplifying implementing configuration options for what is loaded in extensions: Entries in the JSON file could optionally specify a check (callback function) which runs at data loading time, and determines whether or not to add the data for the entry. (But an extension doing this would then have to make sure that for each configuration, a unique key is used for the JSON file, so that old cached data is not reused when configuration changes.)
  • Alternative to the above: using checks in Runtime instead. (No need for changing the key, but some added overhead.) This would also allow, for example, restricting the use of unsafe things to secured namespaces (or using some other criteria). The idea is that such checks can be specified per object, method, function, etc., and the same checking callback can be used everywhere it applies.
  • Building upon the example of secured namespaces, support for those in PhpTags itself: There could be a setting for "secured namespaces", similar to the already existing namespace setting, but also meaning that otherwise restricted things should be allowed in those namespaces. The idea is that things can be marked restricted in the JSON file. When PhpTags is used, it would then check the namespace and allow or deny use of restricted things accordingly. (The advantage of support in PhpTags itself is a single setting for secured namespaces that can be used by all extensions.)

Those are the ideas, whether useful or not.

Hope you have a good time as well!

Pastakhov (talkcontribs)
  • The one exception seems to be constants defined through a callback...
    I agree, so will look even better
  • I'm guessing that objects using it would also be described in the JSON file...
    Yes of course
  • One comment on the PhpTagsHooks API, now that you're changing it: it may make sense to call the public "set..." methods "add..." or "register..." instead, since they do not replace anything, but instead add/register things.
    I'm sorry, but I can not understand what you mean. Can you describe this in more detail or with examples? Yes, thanks.
  • Finally, I had another series of ideas...
    I plan to make such checks at runtime. I thought a lot about it and came to the conclusion that the best solution would be to create a separate class that will be responsible for it. Every time before calling a function or method the runtime will ask permission. In the basic version, the class will check the namespace only. But you can define your own class that can make decisions based on what you need. For example, you can use a random number generator, and throw an exception "this function can not be called because you are out of luck :-)". It should be a really fun :-D
  • Hope you have a good time as well!
    Yes, with you it is better. Thanks :-)

Good Luck!

Pastakhov (talkcontribs)
  • it may make sense to call the public "set..." methods "add..." or "register..." instead ...
    I seem understand :-) I still poorly know English :-( thanks for helping. I'll use 'add' instead 'set'.
Reply to "Designing APIs in PhpTags extensions: limitations and best practices"