diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..54446a1 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: padams +custom: https://paypal.me/openwebanalytics diff --git a/.github/ISSUE_TEMPLATE/01_Bug.md b/.github/ISSUE_TEMPLATE/01_Bug.md new file mode 100644 index 0000000..85fffe6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01_Bug.md @@ -0,0 +1,31 @@ +--- +name: Bug Report +about: Report errors and problems +labels: bug + +--- + +**Before you open an issue:** + +- [ ] I followed the [installation](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/wiki/Installation) or [update](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/wiki/Updating) guide +- [ ] [I read the troubleshooting guide in the wiki](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/wiki/Troubleshooting) + +**Affected Version(s)**: x.y.z + +**PHP Version**: 7.x FPM + +**Webserver**: Apache/Nginx + +**Browser**: Chrome 80.x.x + +**Description** + + +**How to reproduce** + + +**Possible Solution** + + +**Additional context** + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/02_Feature.md b/.github/ISSUE_TEMPLATE/02_Feature.md new file mode 100644 index 0000000..3185a87 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02_Feature.md @@ -0,0 +1,13 @@ +--- +name: Feature Request +about: RFC and ideas for new features and improvements +labels: enhancement + +--- + +**Description** + + +**Example** + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/03_Support.md b/.github/ISSUE_TEMPLATE/03_Support.md new file mode 100644 index 0000000..09615c9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_Support.md @@ -0,0 +1,12 @@ +--- +name: Support Question +about: Question and problems +labels: question + +--- + +**Description** + + +**Example** + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/04_Installation.md b/.github/ISSUE_TEMPLATE/04_Installation.md new file mode 100644 index 0000000..5c5e7c8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/04_Installation.md @@ -0,0 +1,25 @@ +--- +name: Installation Problems +about: Problems with updates or fresh installs +labels: Installation + +--- + +**Before you open an issue:** + +- [ ] I followed the [installation](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/wiki/Installation) or [update](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/wiki/Updating) guide +- [ ] [I read the troubleshooting guide in the wiki](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/wiki/Troubleshooting) + +**Affected Version(s)**: x.y.z + +**PHP Version**: 7.x FPM + +**Webserver**: Apache/Nginx + +**Browser**: Chrome 80.x.x + +**Description** + + +**Additional context** + \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..beb7e6c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,50 @@ +## Pull request checklist + +Please check if your PR fulfills the following requirements: +- [ ] Tested the changes + + +## Pull request type + + + + + +Please check the type of change your PR introduces: +- [ ] Bugfix +- [ ] Feature +- [ ] Code style update (formatting, renaming) +- [ ] Refactoring (no functional changes, no api changes) +- [ ] Other (please describe): + + +## What is the current behavior? + + +Issue Number: N/A + + +## What is the new behavior? + + +- +- +- + +## Does this introduce a breaking change? + +- [ ] Yes +- [ ] No + + + +## Docs need to be updated? + +- [ ] Yes +- [ ] No + + + +## Other information + + \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..8da4166 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at . All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..279a597 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# How to contribute + +I'm really glad you're reading this, because we need volunteer developers to help this project come to fruition. + +## Testing + +Most of the "code" on this repository of the project is eithe PHP, JavaScript or CSS, Please Test your contributions before submitting them + +## Submitting changes + +Please send a [GitHub Pull Request to owa-mediawiki-extension](https://github.com/Open-Web-Analytics/owa-mediawiki-extension/pull/new/master) with a +clear list of what you've done (read more about [pull requests](http://help.github.com/pull-requests/)). +When you send a pull request, we will love you forever if you include comments. +Please follow our coding conventions (below) and make sure all of your commits are atomic (one feature per commit). + +Always write a clear log message for your commits. One-line messages are fine for small changes, but bigger changes should look like this: + + $ git commit -m "A brief summary of the commit + > + > A paragraph describing what changed and its impact." + +## Coding conventions + +Start reading our code and you'll get the hang of it. We optimize for readability: + + * This is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible. + + + diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..25e216a --- /dev/null +++ b/LICENCE @@ -0,0 +1,339 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/Owa/extension.json b/Owa/extension.json new file mode 100644 index 0000000..d8e02b0 --- /dev/null +++ b/Owa/extension.json @@ -0,0 +1,75 @@ +{ + "name": "Open Web Analytics for MediaWiki", + "author": [ + "Peter Adams" + ], + "url": "http://www.openwebanalytics.com", + "description": "Open Web Analytics for MedaWiki", + "version": "1.0", + "license-name": "GPL-2.0-or-later", + "type": "specialpage", + "requires": { + "MediaWiki": ">= 1.33.0" + }, + "ExtensionMessagesFiles": { + "owaAlias": "owa.i18n.alias.php" + }, + "MessagesDirs": { + "owa": [ + "i18n" + ] + }, + "Hooks": { + "ArticlePageDataAfter": [ + "OpenWebAnalyticsHooks::onArticlePageDataAfter" + ], + "SpecialPageExecuteAfterPage": [ + "OpenWebAnalyticsHooks::onSpecialPageAfterExecute" + ], + "CategoryPageView": [ + "OpenWebAnalyticsHooks::onCategoryPageView" + ], + "BeforePageDisplay": [ + "OpenWebAnalyticsHooks::onBeforePageDisplay" + ], + "PageContentInsertComplete": [ + "OpenWebAnalyticsHooks::onPageContentInsertComplete" + ], + "PageContentSaveComplete": [ + "OpenWebAnalyticsHooks::onPageContentSaveComplete" + ], + "ArticleDeleteComplete": [ + "OpenWebAnalyticsHooks::onArticleDeleteComplete" + ], + "LocalUserCreated": [ + "OpenWebAnalyticsHooks::onLocalUserCreated" + ], + "UploadComplete": [ + "OpenWebAnalyticsHooks::onUploadComplete" + ], + "UserLoginComplete": [ + "OpenWebAnalyticsHooks::onUserLoginComplete" + ] + }, + "GroupPermissions": { + "bureaucrat": { + "owa-view": true + } + }, + "AvailableRights": [ + "owa-view" + ], + "SpecialPages": { + "Owa": "SpecialOwa" + }, + "AutoloadClasses": { + "SpecialOwa": "includes/SpecialOwa.php", + "OpenWebAnalyticsInstance": "includes/OpenWebAnalyticsInstance.php", + "OpenWebAnalyticsHooks": "includes/Hooks/OpenWebAnalyticsHooks.php", + "OpenWebAnalyticsAction": "includes/Actions/OpenWebAnalyticsAction.php", + }, + "Actions": { + "OpenWebAnalyticsAction": "OpenWebAnalyticsAction" + }, + "manifest_version": 1 +} diff --git a/Owa/i18n/en.json b/Owa/i18n/en.json new file mode 100644 index 0000000..897ecaf --- /dev/null +++ b/Owa/i18n/en.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Peter Adams" + ] + }, + "owa": "Open Web Analytics", + "owa-linkoncontribs": "Open Web Analytics", + "owa-linkoncontribs-text": "Open Web Analytics", + "owa-desc": "Open Web Analytics integration" +} \ No newline at end of file diff --git a/Owa/includes/Actions/OpenWebAnalyticsAction.php b/Owa/includes/Actions/OpenWebAnalyticsAction.php new file mode 100644 index 0000000..974549e --- /dev/null +++ b/Owa/includes/Actions/OpenWebAnalyticsAction.php @@ -0,0 +1,33 @@ + + * @copyright 2020 WinHelp GmbH + * @version $Id$ + */ + +/** + * Class OpenWebAnalyticsAction + * + * @author Lauser, Nicolai (WinHelp GmbH) + * @copyright 2020 WinHelp GmbH + * @version $Id$ + */ +class OpenWebAnalyticsAction extends Action +{ + public function getName() + { + return 'owa'; + } + + public function show() + { + $this->getOutput()->disable(); + $owa = OpenWebAnalyticsInstance::get(); + $owa->handleSpecialActionRequest(); + } +} \ No newline at end of file diff --git a/Owa/includes/Hooks/OpenWebAnalyticsHooks.php b/Owa/includes/Hooks/OpenWebAnalyticsHooks.php new file mode 100644 index 0000000..a2cfe66 --- /dev/null +++ b/Owa/includes/Hooks/OpenWebAnalyticsHooks.php @@ -0,0 +1,292 @@ + + * @copyright 2020 Peter Adams + * @version $Id$ + */ + +# Protect against web entry +if (!defined('MEDIAWIKI')) { + exit; +} + +/** + * Class OpenWebAnalyticsHooks + * + * @author Peter Adams + * @copyright 2020 Peter Adams + * @version $Id$ + */ +class OpenWebAnalyticsHooks +{ + /** + * @var string[] + */ + private static $_roleLookup = [ + '*' => 'everyone', + 'user' => 'viewer', + 'autoconfirmed' => 'viewer', + 'emailconfirmed' => 'viewer', + 'bot' => 'viewer', + 'sysop' => 'admin', + 'bureaucrat' => 'admin', + 'developer' => 'admin', + ]; + + /** + * @var int[] + */ + private static $_roleHierarchy = [ + 'everyone' => 10, + 'viewer' => 20, + 'admin' => 30, + ]; + + /** + * @param $article + * @param $row + */ + public static function onArticlePageDataAfter($article, $row) + { + $owa = OpenWebAnalyticsInstance::get(); + $owa->setPageTitle($article->getTitle()->getText()); + $owa->setPageType('Article'); + } + + /** + * @param $special + * @param $subPage + */ + public static function onSpecialPageAfterExecute($special, $subPage) + { + $owa = OpenWebAnalyticsInstance::get(); + $owa->setPageTitle($special->getTitle()->getText()); + $owa->setPageType('Article'); + } + + /** + * @param $categoryArticle + */ + public static function onCategoryPageView(&$categoryArticle) + { + $owa = OpenWebAnalyticsInstance::get(); + $owa->setPageTitle($categoryArticle->getTitle()->getText()); + $owa->setPageType('Category'); + } + + /** + * @param OutputPage $out + * @param Skin $skin + */ + public static function onBeforePageDisplay(OutputPage $out, Skin $skin) + { + global $wgRequest, $wgOwaThirdPartyCookies, $wgOwaCookieDomain; + + if ($wgRequest->getVal('action') === 'edit' || $wgRequest->getVal('title') === 'Special:Open_Web_Analytics') { + return; + } + + $owa = OpenWebAnalyticsInstance::get(); + + if (!$owa->getSetting('base', 'install_complete')) { + return; + } + + $cmds = ""; + + if ($wgOwaThirdPartyCookies) { + $cmds .= "owa_cmds.push(['setOption', 'thirdParty', true]);"; + } + + if ($wgOwaCookieDomain) { + $cmds .= "owa_cmds.push(['setCookieDomain', '$wgOwaCookieDomain']);"; + } + + $page_properties = $owa->getAllEventProperties($owa->pageview_event); + + if ($page_properties) { + $page_properties_json = json_encode($page_properties); + $cmds .= "owa_cmds.push(['setPageProperties', $page_properties_json]);"; + } + + $options = ['cmds' => $cmds]; + + $tags = $owa->placeHelperPageTags(false, $options); + $out->addHTML($tags); + } + + /** + * @param $wikiPage + * @param User $user + * @param $content + * @param $summary + * @param $isMinor + * @param $isWatch + * @param $section + * @param $flags + * @param Revision $revision + */ + public static function onPageContentInsertComplete(&$wikiPage, User &$user, $content, $summary, $isMinor, $isWatch, $section, &$flags, Revision $revision) + { + $label = $wikiPage->getTitle()->getText(); + self::trackAction('Article Created', $label); + } + + /** + * @param $actionName + * @param string $label + * @return bool + */ + private static function trackAction($actionName, $label = '') + { + $owa = OpenWebAnalyticsInstance::get(); + + if (!$owa->getSetting('base', 'install_complete')) { + return false; + } + + $owa->trackAction('mediawiki', $actionName, $label); + owa_coreAPI::debug("logging action event " . $actionName); + + return true; + } + + /** + * @param $wikiPage + * @param $user + * @param $mainContent + * @param $summaryText + * @param $isMinor + * @param $isWatch + * @param $section + * @param $flags + * @param $revision + * @param $status + * @param $originalRevId + * @param $undidRevId + */ + public static function onPageContentSaveComplete($wikiPage, $user, $mainContent, $summaryText, $isMinor, $isWatch, $section, $flags, $revision, $status, $originalRevId, $undidRevId) + { + if (!($flags & EDIT_UPDATE)) { + return; + } + + $label = $wikiPage->getTitle()->getText(); + self::trackAction('Article Edit', $label); + } + + /** + * @param $article + * @param User $user + * @param $reason + * @param $id + * @param $content + * @param LogEntry $logEntry + * @param $archivedRevisionCount + */ + public static function onArticleDeleteComplete(&$article, User &$user, $reason, $id, $content, LogEntry $logEntry, $archivedRevisionCount) + { + $label = $article->getTitle()->getText(); + self::trackAction('Article Deleted', $label); + } + + /** + * @param $user + * @param $autocreated + */ + public static function onLocalUserCreated($user, $autocreated) + { + self::trackAction('User Account Added'); + } + + /** + * @param $image + */ + public static function onUploadComplete(&$image) + { + $label = $image->getLocalFile()->getMimeType(); + self::trackAction('File Upload', $label); + } + + /** + * @param User $user + * @param $inject_html + * @param $direct + */ + public static function onUserLoginComplete(User &$user, &$inject_html, $direct) + { + self::trackAction('Login'); + } + + /** + * @param $authStatus + * @return bool + */ + public static function authUser($authStatus) + { + global $wgUser, $wgOwaSiteId; + + if (!$wgUser->isLoggedIn()) { + return false; + } + + $cu = owa_coreAPI::getCurrentUser(); + $cu->setAuthStatus(true); + + $cu->setUserData('user_id', $wgUser->getName()); + $cu->setUserData('email_address', $wgUser->getEmail()); + $cu->setUserData('real_name', $wgUser->getRealName()); + $cu->setRole(self::lookupRole($wgUser->getGroups())); + + // set list of allowed sites. In this case it's only this wiki. + + if (!defined('OWA_INSTALLING')) { + $domains = [$wgOwaSiteId]; + // load assigned sites list by domain + $cu->loadAssignedSitesByDomain($domains); + } + + $cu->setInitialized(); + + return true; + } + + /** + * @param array $groups + * @return string + */ + private static function lookupRole($groups = []) + { + $hierarchyHelper = 0; + $owaRole = 'everyone'; + + foreach ($groups as $group) { + // Role not found just continue + if (!in_array($group, array_keys(self::$_roleLookup))) { + continue; + } + + $currentOwaRole = self::$_roleLookup[$group]; + $currentHierarchy = self::$_roleHierarchy[$currentOwaRole]; + + // Has the current owa role less permission than the previous -> continue + if ($currentHierarchy <= $hierarchyHelper) { + continue; + } + + $owaRole = $currentOwaRole; + + // Hierarchy is already max, stop execution else continue the loop + if (max(array_values(self::$_roleHierarchy)) == $currentHierarchy) { + break; + } + } + + return $owaRole; + } +} \ No newline at end of file diff --git a/Owa/includes/OpenWebAnalyticsInstance.php b/Owa/includes/OpenWebAnalyticsInstance.php new file mode 100644 index 0000000..41d00db --- /dev/null +++ b/Owa/includes/OpenWebAnalyticsInstance.php @@ -0,0 +1,85 @@ + + * @copyright 2020 Peter Adams + * @version $Id$ + */ + +# Protect against web entry +if (!defined('MEDIAWIKI')) { + exit; +} + +/** + * Class OpenWebAnalyticsInstance + * + * @author Peter Adams + * @copyright 2020 Peter Adams + * @version $Id$ + */ +class OpenWebAnalyticsInstance +{ + /** + * @return owa_mw + */ + public static function get() + { + if (isset($GLOBALS['OpenWebAnalytics']) && $GLOBALS['OpenWebAnalytics']) { + return $GLOBALS['OpenWebAnalytics']; + } + + return self::init(); + } + + /** + * @return owa_php + */ + private static function init() + { + global $wgServer, + $wgScriptPath, + $wgMainCacheType, + $wgMemCachedServers, + $wgOwaSiteId; + + require_once(__DIR__ . '/../instance/owa_env.php'); + require_once(OWA_BASE_CLASSES_DIR.'owa_php.php'); + + /* OWA CONFIGURATION OVERRIDES */ + $owa_config = []; + // check for memcache. these need to be passed into OWA to avoid race condition. + if ($wgMainCacheType === CACHE_MEMCACHED) { + $owa_config['cacheType'] = 'memcached'; + $owa_config['memcachedServers'] = $wgMemCachedServers; + } + + if (!$wgOwaSiteId) { + $wgOwaSiteId = md5($wgServer . $wgScriptPath); + } + + $owa = new owa_php($owa_config); + $owa->setSiteId($wgOwaSiteId); + $owa->setSetting('base', 'report_wrapper', 'wrapper_mediawiki.tpl'); + $owa->setSetting('base', 'link_template', '%s&%s'); + $owa->setSetting('base', 'main_url', $wgScriptPath . '/index.php?title=Special:Open_Web_Analytics'); + $owa->setSetting('base', 'main_absolute_url', $wgServer . $owa->getSetting('base', 'main_url')); + $owa->setSetting('base', 'action_url', $wgServer . $wgScriptPath . '/index.php?action=owa&owa_specialAction'); + $owa->setSetting('base', 'rest_api_url', $owa->getSetting( 'base', 'rest_api_url' ).'?'); + $owa->setSetting('base', 'is_embedded', true); + $owa->setSetting('base', 'query_string_filters', 'returnto'); + + // filter authentication + $dispatch = owa_coreAPI::getEventDispatch(); + // alternative auth method, sets auth status, role, and allowed sites list. + $dispatch->attachFilter('auth_status', 'OpenWebAnalyticsHooks::authUser', 0); + + $GLOBALS['OpenWebAnalytics'] = $owa; + + return $owa; + } +} \ No newline at end of file diff --git a/Owa/includes/SpecialOwa.php b/Owa/includes/SpecialOwa.php new file mode 100644 index 0000000..d1de8df --- /dev/null +++ b/Owa/includes/SpecialOwa.php @@ -0,0 +1,103 @@ + + * @copyright 2020 Peter Adams + * @version $Id$ + */ + +# Protect against web entry +if (!defined('MEDIAWIKI')) { + exit; +} + +/** + * Class SpecialOwa + * + * @author Peter Adams + * @copyright 2020 Peter Adams + * @version $Id$ + */ +class SpecialOwa extends SpecialPage +{ + /** + * SpecialOwa constructor. + */ + public function __construct() + { + global $wgOwaEnableSpecialPage; + + parent::__construct('Owa', 'owa-view', $wgOwaEnableSpecialPage); + } + + public function doesWrites() { + return true; + } + + /** + * @param string|null $par + * @throws PermissionsError + */ + public function execute($par) + { + global $wgSitename, + $wgScriptPath, + $wgServer, + $wgDBname, + $wgDBserver, + $wgDBuser, + $wgDBpassword, + $wgOwaSiteId; + + $output = $this->getOutput(); + $this->setHeaders(); + + $output->disallowUserJs(); + $this->checkPermissions(); + + $owa = OpenWebAnalyticsInstance::get(); + $params = []; + + $action = owa_coreAPI::getRequestParam('action'); + + // if no action is found... + if (!($action || empty($action))) { + $output->addHTML($owa->handleRequestFromURL()); + return; + } + + // check to see that owa is installed. + if ($owa->getSetting('base', 'install_complete')) { + $output->addHTML($owa->handleRequest($params)); + return; + } + + define('OWA_INSTALLING', true); + + $siteUrl = $wgServer . $wgScriptPath; + + if (!$wgOwaSiteId) { + $wgOwaSiteId = md5($siteUrl); + } + + $params = [ + 'site_id' => $wgOwaSiteId, + 'name' => $wgSitename, + 'domain' => $siteUrl, + 'description' => '', + 'action' => 'base.installEmbedded', + 'db_type' => 'mysql', + 'db_name' => $wgDBname, + 'db_host' => $wgDBserver, + 'db_user' => $wgDBuser, + 'db_password' => $wgDBpassword, + 'public_url' => $wgServer . $wgScriptPath . '/extensions/Owa/instance/', + ]; + + $output->addHTML($owa->handleRequest($params)); + } +} \ No newline at end of file diff --git a/Owa/instance/.gitkeep b/Owa/instance/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Owa/owa.i18n.alias.php b/Owa/owa.i18n.alias.php new file mode 100644 index 0000000..7ee388e --- /dev/null +++ b/Owa/owa.i18n.alias.php @@ -0,0 +1,26 @@ + + * @copyright 2020 WinHelp GmbH + * @version $Id$ + */ +/** + * Aliases for myextension + * + * @file + * @ingroup Extensions + */ + +$specialPageAliases = []; + +/** English + * @author + */ +$specialPageAliases['en'] = [ + 'Owa' => [ 'Open_Web_Analytics'], +]; \ No newline at end of file