Sly_Ripper Posted June 18, 2023 Posted June 18, 2023 (edited) 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, 2023 by Sly_Ripper
teraßyte Posted June 18, 2023 Posted June 18, 2023 (edited) 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, 2023 by teraßyte
Sly_Ripper Posted June 18, 2023 Author Posted June 18, 2023 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' ) );
teraßyte Posted June 18, 2023 Posted June 18, 2023 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.
Sly_Ripper Posted June 19, 2023 Author Posted June 19, 2023 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(); } }
teraßyte Posted June 19, 2023 Posted June 19, 2023 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. 😅
Sly_Ripper Posted June 19, 2023 Author Posted June 19, 2023 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?
teraßyte Posted June 19, 2023 Posted June 19, 2023 (edited) 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, 2023 by teraßyte
Sly_Ripper Posted June 22, 2023 Author Posted June 22, 2023 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
Stuart Silvester Posted June 22, 2023 Posted June 22, 2023 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.
Sly_Ripper Posted June 22, 2023 Author Posted June 22, 2023 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');
Solution Stuart Silvester Posted June 22, 2023 Solution Posted June 22, 2023 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;
Sly_Ripper Posted June 23, 2023 Author Posted June 23, 2023 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
Recommended Posts