Jump to content


Daniel F

Invision Community Team
  • Posts

  • Joined

  • Days Won


 Content Type 



IPS4 Providers

Release Notes

IPS4 Guides

IPS4 Developer Documentation

Invision Community Blog



Everything posted by Daniel F

  1. Almost all form fields are handled via Form Helpers so if you need to change any of these fields, you'll have to search for the method which creates the form, then you can create a hook to change the form fields! There are few methods where above approach won't work, in this case you can create a hook on \IPS\Helpers\Form\FormAbstract to override the constructor to adjust the field data 🙂
  2. Yea, IPS\Dispatcher\Standard seems like a good spot! If you care about literally anything and if you want to log "everything" , you could even hook into IPS\Dispatcher! I'm doing something similar with rollbar: //<?php /* To prevent PHP errors (extending class does not exist) revealing path */ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { exit; } abstract class rollbar_hook_dispatcher_standard extends _HOOK_CLASS_ { public function init() { $this->initRollbar(); parent::init(); } protected function initRollbar() { if ( \IPS\Settings::i()->rollbarapikey ) { require_once \IPS\Application::getRootPath('rollbar') . '/sources/vendor/autoload.php'; $config = array( 'access_token' => \IPS\Settings::i()->rollbarapikey, 'environment' => \IPS\Settings::i()->base_url, 'root' => \IPS\ROOT_PATH ); \Rollbar\Rollbar::init($config); } } }
  3. You should mention that people could notice performance issues because of this! As mentioned in one of the tickets, it's not that smart to disable the widget cache. It's probably working on smaller boards but literally going to kill any medium & big boards with many topics or other items which the widget is trying to show!
  4. Well, it's actually visible, but it's white on a white background. You should probably change the color or add a border 🙂
  5. I have filled a bug report for this.
  6. You could use custom variables to differ between logged in members and guests.
  7. You wanna probably take a look at following file which is IMO the best enhancement here
  8. This could be a custom theme issue, or an issue with the htaccess or configuration file. Please submit a ticket so that we can take a look at this.
  9. Thanks, this seems to be a valid issue which is also affecting few other areas and apps. I have posted this to our internal bug tracker.
  10. Why would you want to get a friendly url for http://ips.valacoding.com/index.php?app=core&module=system&controller=widgets&do=getBlock&blockID=app_nexus_latestProducts_tfxsn9iaq&pageApp=nexus&pageModule=store&pageController=product&pageArea=header&orientation=horizontal..... ? The page is meant to be shown in a modal and only to moderators with permissions to edit the sidebar, there's no point in having a friendly url here.
  11. Do you see any errors in the browsers JS console? Have you tried running the support tools in the ACP?
  12. Thanks, I have fixed this for an upcoming release.
  13. You could use live templates or snippets to automate this;) I have probably 50 snippets making my life easier:) https://www.jetbrains.com/help/pycharm/tutorial-creating-and-applying-live-templates-code-snippets.html Or, if it's only for your own usage, create some helper functions if(!function_exists('l')) { function l() { $args = \func_get_args(); return \IPS\Member::loggedIn()->language()->addToStack( ...$args ); } } if(!function_exists('lg')) { function lg($key) { return \IPS\Member::loggedIn()->language()->get( $key ); } }
  14. Sorry, it was the wrong constant! I have edited my post in the meanwhile. It's NOTIFICATIONS_PER_BATCH which handles this. Sorry again for the confusion.
  15. Yes, this is handled via the NOTIFICATIONS_PER_BATCH constant.
  16. Trust me, as the first in the IPS team from a none English speaking country I've brought up many ideas for the language system, but the language system in IPS 4.x is unfortunatly quite limited and requires a full rewrite, which is not feasible at the moment.
  17. You can control this via module permissions
  18. Yea, that's not intentional and I can't reproduce it myself on our own community and my priv. board with Safari. Are you seeing this here on the community or only on your own community? I guess a ticket would be the best guess to investigate this further:)
  19. What it does An AchievementAction extension allows you to define custom actions for Achievement Rules. Note that you do not ever have to think directly about points or badges. You just tell the system about your actions, and when they happen. The framework will handle including your actions in the UI that allows administrators to configure what points and badges are awarded from there, and handle giving them out (although you don't nee to worry about this, details of how this happens is below). A action always has a subject member. For example, the user making the post, logging in, or receiving a reaction. When you call the user-land code defined above, you call it on the subject member's \IPS\Member object. An action can also optionally have any other members (with the awardOptions() method in the extension). For example, the user giving a reaction, the user who originally posted a question which is getting an answer marked best, or the club leader(s) of a club being joined. This allows you to create single actions which can award points to multiple members. An action can have filters allowing the administrator to create different rules for different scenarios. For example, an administrator might want to award certain amounts of points for posting in one forum and other amounts for other forums. Again, all you need to do is tell the system about your filters (with the filters() and formatFilterValues() methods in the extension) and provide a callback in your extension for checking if a given scenario matches (with the filtersMatch() method in the extension). You do not need to do anything in your user-land code. In addition to filters for things like which node a thing is happening in, a common filter type will be a "milestone" filter - i.e. "if this is the member's first/100th/whatever time they've done this thing". This will be especially useful for allowing administrators to create badge-earning rules on specific occasions rather than points-based rules every time a thing happens. Despite it probably being a feature of most actions, it is ultimately just the same as any other filter. The framework will automatically log the event and the points/badges that were issued because of it, including checking that log to make sure the user doesn't earn rewards more than once. For example, if a member likes a post, unlikes it, and re-likes it, the framework will see from the log they have already earned rewards for that and not give them again. You do not need to do anything in user-land code to facilitate this, except provide a callback that return a unique string identifier (with the identifier() method in the extension). For example, if your action is for when a post is created, you would return the post ID. If your action is for when a reaction is given you would need to return a string that encapsulates both the content ID and the giver's member ID. Sometimes you can use this to get a bit creative. For example, the SessionStartDaily action is called every time a member logs in, and the identifier used is a string representation of the member ID + current date. This means the action can give points every unique day that the member logs in, and we don't need to implement any logic to facilitate that: we just set the identifier to be unique for the timeframe that it should occur within, and the system figures it out. If more than one rule matches for a particular action, they all execute. For example, if you have a rule that gives 1 point for posting in any forum, and another which gives 5 points for posting in a special forum, the user will earn 6 points for posting in that second forum. How to use 1. Create the extension and implement the below methods. 2. In userland code, call Member::achievementAction() to trigger the action. $member->achievementAction( 'your_app_key', 'YourAchievementActionExtensionKey', $anyExtraDataThatYouNeed ); /** * Get filter form elements * * @param array|NULL $filters Current filter values (if editing) * @param \IPS\Http\Url $url The URL the form is being shown on * @return array */ public function filters( ?array $filters, \IPS\Http\Url $url ): array { return []; } The filters method defines the custom form fields when the specific action is being used. /** * Format filter form values * * @param array $values The values from the form * @return array */ public function formatFilterValues( array $values ): array { return []; } The formatFieldValues method is called before the form is saved, allowing you to prepare the form values. /** * Work out if the filters applies for a given action * * Important note for milestones: consider the context. This method is called by \IPS\Member::achievementAction(). If your code * calls that BEFORE making its change in the database (or there is read/write separation), you will need to add * 1 to the value being considered for milestones * * @param \IPS\Member $subject The subject member * @param array $filters The value returned by formatFilterValues() * @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object) * @return bool */ public function filtersMatch( \IPS\Member $subject, array $filters, $extra = NULL ): bool { return TRUE; } /** * Return a description for this action to show in the log * * @param string $identifier The identifier as returned by identifier() * @param array $actor If the member was the "subject", "other", or both * @return string */ public function logRow( string $identifier, array $actor ): string { return "{class}"; } /** * Get "description" for rule * * @param \IPS\core\Achievements\Rule $rule The rule * @return string|NULL */ public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string { return "{class}"; } /** * Process the rebuild row * * @param array $row Row from database * @param array $data Data collected when starting rebuild [table, pkey...] * @return void */ public static function rebuildRow( $row, $data ) { // This method runs the achievementAction on the table row from the table (or tables) you specified in rebuildData() // You are welcome to load any classes, etc you need here. //IPS\Member::loggedIn()->achievementAction( '{app}', '{class}', $row['field_id'] ), \IPS\DateTime::ts( $row['field_date'] ) ); } /** * Get rebuild data * * @param array $data Data stored with the queue item * @param array $filters The value returned by formatFilterValues() * @param \IPS\DataTime|null $time Any time limit to add * @return void */ public function preRebuildData( &$data, $filters, \IPS\DateTime $time = NULL ) { /* Any data for the rebuild task, must set $data['count'] for the progress bar */ } The preRebuildData() method allows the extension to calculate and store any data necessary prior to initiating the rebuild task and it also needs to include the number of items in the DB which are going to be processed for the progress bar.
  20. New Extensions: core\AchievementAction Supported PHP & MySQL Versions: The PHP min version was increased to PHP 7.2 in IPS 4.6, this means that your marketplace submissions are required to work with this version, but keep in mind that few clients are going to use php8, so I would really suggest to try to get your code working with both versions, which means that you'll need to implement some changes to avoid some BC breaks in PHP8. Here's a great list https://www.php.net/manual/en/migration80.incompatible.php Security Improvements: We have a new IN_DEV code check similar to the slash check, which will inform you about any outputs containing the CSRF key in the URL. This is a bad practice allowing attackers and 3rd parties to obtain the users CSRF key, so please try avoid this at any cost! We're not going to reject MP submissions because of this, but please try to avoid this as much as much as possible. New Content Framework Feature: Anonymous Content
  21. We took the opportunity for some spring cleaning and to clean up the 4.6 code, so we have finally removed most of the methods which were marked as deprecated. Removed \IPS\{app}\extensions\core\Uninstall\{extension}::onOtherAppUninstall() (use onOtherUninstall()instead). Removed \IPS\cms\Databases::getDatabaseDataFromStore() (use getStore() instead). Removed \IPS\cms\Pages\Page::getPageUrlStore() (use getStore() instead). Removed \IPS\Application::$ipsApps (use \IPS\IPS::$ipsApps instead). Removed \IPS\Login::handlers() (use getStore() instead, but note that the response is formatted differently). \IPS\Email::buildFromContent() now requires the $type parameter to be passed. \IPS\Email::buildFromTemplate() now requires the $type parameter to be passed. Removed \IPS\File::getConfigurations() (use getStore() instead). $isInternal and $isFriendly properties in the URL classes have been removed. Check instanceof \IPS\Http\Url\Internal and instanceof \IPS\Http\Url\Friendly instead. Removed \IPS\core\Rss::getAllFeeds() (use getStore() instead). Removed \IPS\Content\Reaction::reactionStore() (use getStore() instead). Removed \IPS\Content\ShareServices\Facebook::publish(). Removed \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS. This behavior was already deprecated and throwing IN_DEV warnings in past versions. Removed \IPS\Email::buildUnsubscribe() (use setUnsubscribe() instead). Removed \IPS\Helpers\Form\Address::_calculateDefaultCountry() (use calculateDefaultCountry() instead, and note that it is a static method). Removed \IPS\Http\Url::getFurlQuery() (check $friendlyUrlComponent instead). Removed \IPS\Http\Url::csrf() (this method still exists for internal URL instances of \IPS\Http\Url\Internal). Removed \IPS\Http\Url::acpQueryString() (this method still exists for internal URL instances of \IPS\Http\Url\Internal). Removed \IPS\Http\Url::stripArguments()`. Removed \IPS\Http\Url::createFromArray(). Removed \IPS\Http\Url::rfc3986(). Removed \IPS\Http\Url::getFriendlyUrlData() (check $hiddenQueryString on an instance of \IPS\Http\Url\Friendly instead). Removed \IPS\Log::i()->write() (use \IPS\Log::log() and \IPS\Log::debug()` instead). Removed \IPS\Login\LoginAbstract`. This class provided an upgrade path for 4.2 login handlers when 4.3 was initially released. Removed \IPS\Member\Group::groupStore() (use getStore() instead). Removed \IPS\Member::get_pp_photo_type() (use the magic ->pp_photo_type property instead). Removed \IPS\Output::licenseKeyWarning() and \IPS\Output::licenseKeyDaysRemaining(). Removed \IPS\Theme::i()->logo_sharer and \IPS\Theme::i()->logo_favicon as these are no longer theme-specific images.
  22. Hey, we have published the first article of a series about upcoming 4.6 changes. We took the opportunity for some spring cleaning, so we have removed most of the deprecated methods! They were all marked as deprecated for a while, so you should already be aware of these methods, but here’s a full list of the methods and the new approaches to make your life easier, so if you haven’t already, now it’s the best time to review your code and make sure that none of these methods is used. Most of the changes can already be implemented while the 4.5.x lifecycle.
  23. In some cases, the group won't matter. Even if the user is in the admin group, he won't be able to access the ACP if the admin group was removed from being able to access the ACP ( Admin => Members => Administrators) Anyway, please see your ticket reply so that we can resolve this ASAP 🙂
  24. 500 errors should be logged in the servers error log
  25. There was a setting in vBulletin where you could define a time cutoff ( 30 days by default) and then it would just count the members which were online in these last X days and return them as active members. Quite useless statistic for the frontend IMO:)
  • Create New...

Important Information

We use technologies, such as cookies, to customise content and advertising, to provide social media features and to analyse traffic to the site. We also share information about your use of our site with our trusted social media, advertising and analytics partners. See more about cookies and our Privacy Policy