Jump to content

TSP

Clients
  • Posts

    6,674
  • Joined

  • Last visited

  • Days Won

    9

TSP last won the day on August 7 2022

TSP had the most liked content!

Profile Information

  • Gender
    Male
  • Location
    Norway

Recent Profile Visitors

111,119 profile views
  1. TSP

    IC5: Theme Tools

    Yeah, I have to say I'm also worried about ad placement. We need a lot of control over how and where they are included. For example we have some ads which should display as a "horseshoe" around the content. To achieve this currently we have our own wrapper class around the necessary elements etc. Also, from looking in the video from Ehren there is a lot of settings to control and clicking into all sorts of menus with settings. Will there be some way to control it by editing a json file instead for example? That would make it easier and faster for many of us frontend and backend programmers to copy theme settings between different installations etc. Essentially what I'm asking for would be a "source mode" for the theme editor settings view on the frontend.
  2. TSP

    IC5: Theme Tools

    A few questions at the top of my mind, I'll probably have some later too. Currently I've made a shared core theme where all our customizations for five different forum installations are. So the HTML, Javascript and CSS is kept the same, but some different output, logic and elements are displayed or utilized based on logic that depends on the value in custom theme variables. I assume there is still some tool to export and import/upgrade custom templates and template hooks? Having to log in to each admin panel and define all these custom templates and hooks would be a pain. Is custom theme variables still a thing and accessible within these templates? And will theme variables that have been modified on the installation be reset or kept upon upgrade/import of a theme? Will the same variables and functions we have available to us when making a template hook today be available to us from these new custom templates and hooks? I realize the names of methods, how you may invoke them, template logic etc., will be different, but my point is; will all the variables and functions that can be used in the template we hook into be available to us?
  3. The "Geolocation based registration filtering" sounds good, but maybe you could also provide an option to flip it to a whitelist? So you can choose a global setting that'll apply when a geolocation filter entry for the country is not present, and then you'll add the countries that should be treated differently/whitelisted instead.
  4. Sorry for the delay, things have unfortunately been hectic on my end. It also turned out I locally had a slightly different version of 1.2.3 which caused me not be able to reproduce. I've seen in a new minor update, 1.2.3.1, for Marketplace review. Hopefully it gets approved soon, I've sent a headsup to someone at Invision 🙂
  5. Hi, could you post the error here or send me a PM? I don't get any such warnings myself.
  6. It seems the only way to get push alerts on iOS is to choose "Standalone" as the display mode in the manifest. Problem I see is that if any page in the community takes a bit long too load, it looks to the user as if nothing is happening. In the standard Safari iOS browser you can see the loading indication under the address bar that pops up when you click something, but nothing like that appears in a standalone web-app. Obviously slow loading times should be investigated and resolved, but I feel there should still be some feedback from the UI that loading is in progress, otherwise the user will just try to click multiple times. I'm not sure if there's something that could be added to the manifest to resolve this, or if you could work on something else, but I think you should investigate some UX improvement here.
  7. I think it's good SEO-improvements is done, but in this case I feel it's at the expense of guest user experience. Why can't this be solved with indicating nofollow or adding it to robots.txt? If the link is not gonna take you to what you expect as a guest, then why have it be a link for them in the first place.
  8. I'll be working on a project in a few weeks which would require parts of the community to be embeddable on an external site. They should be able to do basic actions such as registering, logging in, reading topics and replying to topics all within the iframe on the external site. The height reserved for the iframe on the external site should be dynamic and change whenever the height of the embedded page changes. My idea thus far is to solve this by asking them to include an iframe on the external page. I'll obviously be adding a Content Security Policy so the community can't be included everywhere. My initial thought on the approach to do this would be to create a separate page or pages on the community where I add the required elements one by one/create the templates/CSS/javascript etc. from "scratch". So for example the URL for the iframe would be: Community.com/iframe/Topic.php?tid=10000 However, I'm starting to think that a better apporach might be to solve this by creating a very simplified and stripped down theme optimized for iframe-embedding. That theme would then be used automatically when the community is embedded in an iframe and/or when a certain URL-parameter is added to the URL, for example: invisioncommunity.com/forums/topic/458426-critical-resource-updates/?display=iframe Which approach would you recommend, and do you have any other tips or things I should be aware of? I'm just sort of in the phase of thinking a bit about it in the back of my mind, so any pointers and hints on the best ways to approach and develop this, and the tools to use, would be appreciated!
  9. I recently upgraded a community and we noticed guests no longer get the ?do=getLastComment link on "timestamp links", for example the timestamp link in the last reply column in topic lists. The link is now the same as the title link which just goes to the first page.
  10. Can the default action when deleting a member be changed from Delete to Leave? In our case it will always be "Leave" and "Continue to attribute" (we change member name to random string before deleting)
  11. I'll also jump in here and confirm that our moderators get this error a lot. Examples: Unknown or bad format (P-1Y11M24DT2M3S) #0 /data/ipsdiskcache/prod/template_2_e554b6dcaef0395bbd7d6d63ba187d0a_modcp.php(6271): DateInterval->__construct('P-1Y11M24DT2M3S') #1 //system/Theme/SandboxedTemplate.php(61): IPS\Theme\Cache\class_core_front_modcp->warnHovercard(Object(IPS\core\Warnings\Warning)) #2 //applications/core/modules/front/system/warnings.php(116): IPS\Theme\_SandboxedTemplate->__call('warnHovercard', Array) #3 //system/Dispatcher/Controller.php(107): IPS\core\modules\front\system\_warnings->view() #4 //system/Content/Controller.php(50): IPS\Dispatcher\_Controller->execute() #5 //applications/core/modules/front/system/warnings.php(42): IPS\Content\_Controller->execute() #6 //system/Dispatcher/Dispatcher.php(153): IPS\core\modules\front\system\_warnings->execute() #7 //index.php(13): IPS\_Dispatcher->run() #8 {main} Exception: Unknown or bad format (P-1Y11M24DT2M3S) (0) #0 //applications/core/sources/Warnings/Warning.php(400): DateInterval->__construct('P-1Y11M24DT2M3S') #1 //system/Content/Item.php(463): IPS\core\Warnings\_Warning->processAfterCreate(NULL, Array) #2 //system/Content/Item.php(143): IPS\Content\_Item::createFromForm(Array, NULL) #3 //applications/core/modules/front/system/warnings.php(140): IPS\Content\_Item::create() #4 //system/Dispatcher/Controller.php(107): IPS\core\modules\front\system\_warnings->warn() #5 //system/Content/Controller.php(50): IPS\Dispatcher\_Controller->execute() #6 //applications/core/modules/front/system/warnings.php(42): IPS\Content\_Controller->execute() #7 //system/Dispatcher/Dispatcher.php(153): IPS\core\modules\front\system\_warnings->execute() #8 //index.php(13): IPS\_Dispatcher->run() #9 {main} #0 //init.php(1029): IPS\_Log::log('Exception: Unkn...', 'uncaught_except...') #1 [internal function]: IPS\IPS::exceptionHandler(Object(Exception)) #2 {main}
  12. I see the following error a lot in our system logs after updating from PHP 7.4 to 8.1: TypeError: in_array(): Argument #2 ($haystack) must be of type array, int given (0) #0 /*/system/Content/Content.php(1714): in_array(300, -1) #1 /*/system/Content/Controller.php(3001): IPS\_Content->report('', '2') #2 /*/system/Content/Controller.php(2271): IPS\Content\_Controller->_report('IPS\\forums\\Topi...', Object(IPS\forums\Topic\Post), Object(IPS\forums\Topic)) #3 /*/applications/forums/modules/front/forums/topic.php(1240): IPS\Content\_Controller->__call('_report', Array) #4 /*/system/Dispatcher/Controller.php(107): IPS\forums\modules\front\forums\_topic->__call('reportComment', Array) #5 /*/system/Content/Controller.php(50): IPS\Dispatcher\_Controller->execute() #6 /*/applications/forums/modules/front/forums/topic.php(39): IPS\Content\_Controller->execute() #7 /*/system/Dispatcher/Dispatcher.php(153): IPS\forums\modules\front\forums\_topic->execute() #8 /*/index.php(13): IPS\_Dispatcher->run() #9 {main} This TypeError doesn't prevent the report from being submitted, but it causes a redirect in the browser (because of an ajax call not receiving the expected reply) to the report page for the content, where the user will be told they've already reported it. In Content.php at or around line 1714: <?php if ( ! in_array( $item->mapped('container'), $perms[ $container::$modPerm ] ) ) As seen in the error pasted above, the first parameter was 300 (referring to the forum id), while the second parameter supplied is -1. The value of $container::$modPerm is "forums", and the value of $perms['forums'] is just -1. This is because, while the moderator or moderator groups is restricted, they are unrestricted in which forums they are able to operate, and then you save it as -1 to the forums-key in the json value for the perms-column in ibf_core_moderators.
  13. After upgrading the server of one of our communities from PHP 7.4 to 8.1 I found the following error message popping up a lot: TypeError: count(): Argument #1 ($value) must be of type Countable|array, string given in /www/system/Data/Cache.php:151 This was caused by some custom code being referenced in a custom theme which requested a value with \IPS\Data\Cache::getWithExpire. This is how that function looks currently: <?php public function getWithExpire( $key, $fallback=FALSE ) { if ( !isset( $this->$key ) ) { throw new \OutOfRangeException; } $data = $this->$key; if( \count( $data ) and isset( $data['value'] ) and isset( $data['expires'] ) ) { // ... } else { unset( $this->$key ); throw new \OutOfRangeException; } } After some debugging I found that $data was indeed a string, and thus can't be counted. My first thought was that you should change from \count( $data ) to \is_array( $data ) in this function, which I still think you should, but the next mystery was to figure out why it would be a string, since you always expect it to be an array, and I used the regular storeWithExpire to save to Cache. I found the culprit to be former abundance of caution, or what might have been a good reason at the time I implemented it (many many years ago): My code would first request the cache key from \IPS\Data\Cache::getWithExpire. If it didn't find it saved in Cache or it was expired, it would move on to check \IPS\Data\Store, with a 1/15 chance of unsetting it in \IPS\Data\Store to prevent the value from "never" being updated. If it didn't find it in any of them, then it would request the value from an external source and save it to both Data\Cache and Data\Store. But if both methods utilizes Redis, then it means the second method will just overwrite the cache entry that the first one saved. Data\Cache stores an array to the cache key in Redis, but then Data\Store would immediately overwrite the same cache entry with a string. You can reproduce with this code: <?php require_once 'init.php'; $cacheKey = 'storeItPlease3'; $saveToCache = 'Hello world :-) | ' . date(DATE_RFC2822); $expire = \IPS\DateTime::ts( time() + 60 ); try { $cached = \IPS\Data\Cache::i()->getWithExpire( $cacheKey, TRUE ); echo $cached . "\n"; } catch ( \OutOfRangeException $e ) { try { $cached = \IPS\Data\Store::i()->{$cacheKey}; echo "Found in store: {$cached}\n"; if ( rand(1, 15) == 15 ) { unset(\IPS\Data\Store::i()->{$cacheKey}); } } catch(\OutOfRangeException $e2) { echo "Couldn't find in Data\Store!\n"; } echo "Didn't find {$cacheKey}. Write it!\n"; \IPS\Data\Cache::i()->storeWithExpire( $cacheKey, $saveToCache, $expire, TRUE ); \IPS\Data\Store::i()->{$cacheKey} = $saveToCache; } While I understand this kind of situation arising being rare and you probably don't expect people using both methods simultaneously like this, I thought I would still make you aware of it in case you encounter similar reported issues in the future and maybe make some changes to your code. Having a key name be the same in both Store and Cache could also happen by accident, although I guess the chance is rare. Consider use is_array() rather than, or in addition to count() in \IPS\Data\Cache::getWithExpire (Do you even need that first check, maybe it's enough with the isset()-calls?) Consider prepending or appending to the cache key for one of the storage methods to differentiate entries in Redis saved by Store and Cache (Alternatively document that one shouldn't use a key for Store that's already used by Cache or vice versa)
×
×
  • Create New...