Invision Community 4: SEO, prepare for v5 and dormant account notifications Matt November 11, 2024Nov 11
Posted June 18, 20231 yr Fresh install, trying to add an API route but Member::load breaks any time I pass $idField, even default fields. works: $member = \IPS\Member::load(1); $member = \IPS\Member::load(1, 'member_id'); Returns { "errorCode": "EX0", "errorMessage": "" } System log says "InvalidArgumentException (0)", viewing the log shows OutOfRangeException from line 115 /app/system/Patterns/ActiveRecord.php Also, the docs need fixing: /** * Add our own column to default fields */ public function __construct() { static::$databaseIdFields = array_merge( static::$databaseIdFields, array( 'remote_id' ) ); } parent::__construct(); Edited June 18, 20231 yr by Sly_Ripper
June 18, 20231 yr You can only use the allowed values in the \IPS\Member class for the second parameter: /** * @brief [ActiveRecord] Database ID Fields */ protected static $databaseIdFields = array( 'name', 'email' ); If you want to load based on the member_id column, simply skip the second parameter. You need to provide it only if you're loading a member based on their name or email address. Edited June 18, 20231 yr by teraßyte
June 18, 20231 yr Author 47 minutes ago, teraßyte said: You can only use the allowed values in the \IPS\Member class for the second parameter: /** * @brief [ActiveRecord] Database ID Fields */ protected static $databaseIdFields = array( 'name', 'email' ); If you want to load based on the member_id column, simply skip the second parameter. You need to provide it only if you're loading a member based on their name or email address. Ah you're right. What about with custom columns? My hook is valid since inputting a column that doesn't exist here throws an error, with a valid column it throws the same error as before: static::$databaseIdFields = array_merge( static::$databaseIdFields, array( 'remote_id' ) );
June 18, 20231 yr As long as you fixed the parent call being outside the function in the example, it should work. I you post here the hook's code I can take a quick look maybe.
June 19, 20231 yr Author 12 hours ago, teraßyte said: As long as you fixed the parent call being outside the function in the example, it should work. I you post here the hook's code I can take a quick look maybe. It's literally just a fresh hook and the example code //<?php /* To prevent PHP errors (extending class does not exist) revealing path */ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { exit; } class appname_hook_CustomMemberColumns extends _HOOK_CLASS_ { /** * Add our own column to default fields */ public function __construct() { static::$databaseIdFields = array_merge( static::$databaseIdFields, array( 'remote_id' ) ); parent::__construct(); } }
June 19, 20231 yr Yes, that seems indeed correct. Try adding this code right before the parent call: var_dump( static::$databaseIdFields );exit; If the hook is being loaded properly, you should get an output of 3 values: name, email, remote_id. If you don't get anything, maybe there's a typo in the class you're trying to extend. Something like \IPS\Members instead of \IPS\Member. I had it happen a few times. 😅
June 19, 20231 yr Author 55 minutes ago, teraßyte said: Yes, that seems indeed correct. Try adding this code right before the parent call: var_dump( static::$databaseIdFields );exit; If the hook is being loaded properly, you should get an output of 3 values: name, email, remote_id. If you don't get anything, maybe there's a typo in the class you're trying to extend. Something like \IPS\Members instead of \IPS\Member. I had it happen a few times. 😅 array(3) { [0]=> string(4) "name" [1]=> string(5) "email" [2]=> string(9) "remote_id" } Still throws an error when trying to load a member with 'remote_id'. Being in an API route shouldn't make a difference?
June 19, 20231 yr I think we need to take a step back and start from scratch here. What are you trying to do exactly? If you just need to load a member by using their ID, you don't need the hook or the remote_id value. Or are you trying to load a member based on some kind of external ID after adding a remote_id column to the core_members table in the database? Knowing your goal would help guide you in the correct direction. Edited June 19, 20231 yr by teraßyte
June 22, 20231 yr Author On 6/19/2023 at 5:30 PM, teraßyte said: I think we need to take a step back and start from scratch here. What are you trying to do exactly? If you just need to load a member by using their ID, you don't need the hook or the remote_id value. Or are you trying to load a member based on some kind of external ID after adding a remote_id column to the core_members table in the database? Knowing your goal would help guide you in the correct direction. 2 @Matt this is either a bug or bad docs
June 22, 20231 yr We've used this approach in a lot of plugins, so I know it's working properly. Make sure that you actually have a `remote_id` column created in the `core_members` table. It may also be worthwhile to show the log from the system log page in the support section. The JSON is not a real error. Although, these days we would recommend keeping track of SSO data in your own table so that you're not modifying core tables.
June 22, 20231 yr Author 10 minutes ago, Stuart Silvester said: We've used this approach in a lot of plugins, so I know it's working properly. Make sure that you actually have a `remote_id` column created in the `core_members` table. It may also be worthwhile to show the log from the system log page in the support section. The JSON is not a real error. Although, these days we would recommend keeping track of SSO data in your own table so that you're not modifying core tables. I mentioned the line that throws the error in the first post, using the doc's code, '$databaseIdFields' is not being overwritten by the hook correctly. #0 /app/system/Member/Member.php(240): IPS\Patterns\_ActiveRecord::load() #1 /app/applications/appname/api/members.php(28): IPS\_Member::load() #2 /app/system/Api/Controller.php(180): IPS\appname\api\_members->GETitem() #3 /app/system/Dispatcher/Api.php(343): IPS\Api\_Controller->execute() #4 /app/api/index.php(11): IPS\Dispatcher\_Api->run() #5 {main} Doing it this way works, probably not the best idea though: class appname_hook_CustomMemberColumns extends _HOOK_CLASS_ { protected static $databaseIdFields = array('name', 'email', 'remote_id');
June 22, 20231 yr Solution Thanks for the follow up. That helps explain the issue you're having. When you're updated the allowed IDs in the __construct() method, the \IPS\Member object has to be instantiated in order for that code to run. This happens automatically when using this code has a front/admin session available in normal use on the front end (which is why we're all expecting it to be working). Solving this (although not pretty) would be as simple as putting this in your code before you load the member. new \IPS\Member;
June 23, 20231 yr Author 19 hours ago, Stuart Silvester said: Thanks for the follow up. That helps explain the issue you're having. When you're updated the allowed IDs in the __construct() method, the \IPS\Member object has to be instantiated in order for that code to run. This happens automatically when using this code has a front/admin session available in normal use on the front end (which is why we're all expecting it to be working). Solving this (although not pretty) would be as simple as putting this in your code before you load the member. new \IPS\Member; Solved, thanks