Jump to content

Leaderboard


    • Points

      3

    • Posts

      790


  1. Cpl Clendaniel

    Infantryman


    • Points

      3

    • Posts

      309



    • Points

      2

    • Posts

      1934


  2. HMC (FMF) T. Savage

    Systems Lead Developer


    • Points

      1

    • Posts

      1127


Popular Content

Showing content with the highest reputation on 08/26/22 in Posts

  1. After two years of no longer using folders because my account's folders were broken by the above issue, it has been tracked down and resolved! Well... Until we update to a newer version of IPS and I have to fix it manually. So here's to hoping Invision Community resolves this issue with the following synopsis. Enclosed, I will use the example folder names above to keep things consistent and easier to illustrate. What was the issue? When using folders, you're able to reduce the size of your inbox and organize messages to be easier to find. I created multiple folders and loved the new organization and mild "neatness" I began to experience. As I moved positions, some of those folders became irrelevant and I deleted those folders to restructure. When I started reorganizing messages in my inbox, I quickly discovered the issue above. I was moving messages into "Folder Four" using the message list checkbox and dialog that prompted me which folder to move the message(s) to, but my messages were landing into "Folder Three" instead. I thought it was a one-time issue, so I again moved the message trying "Folder One" and it worked flawlessly. I retried "Folder Four", but the message was put into "Folder Three" once again. So let's look at the code for the "View Folder" drop-down and see what sort of "identifiers" are used by IPS when I try to navigate these folders. <!-- Irrelevant HTML attributes removed for readability --> <ul id="elMessageFolders_menu"> <li data-ipsmenuvalue="myconvo"><a href="https://forums.example.com/messenger/"><span data-role="folderName">Inbox</span></a></li> <li data-ipsmenuvalue="0"><a href="https://forums.example.com/messenger/?folder=0"><span data-role="folderName">Folder One</span></a></li> <li data-ipsmenuvalue="2"><a href="https://forums.example.com/messenger/?folder=2"><span data-role="folderName">Folder Three</span></a></li> <li data-ipsmenuvalue="3"><a href="https://forums.example.com/messenger/?folder=3"><span data-role="folderName">Folder Four</span></a></li> <li><a href="..." data-action="addFolder" id="elAddFolder">Add Folder</a></li> </ul> Very quickly, we can see the URLs contain a number sequence EXCEPT the position 1 is missing. If your recall my steps above, the folder in between "Folder One" and "Folder Three" would have been the since-deleted "Folder Two". So I validated this by creating one more folder called "Folder Five" and then I deleted "Folder Four". <!-- Irrelevant HTML attributes removed for readability --> <ul id="elMessageFolders_menu"> <li data-ipsmenuvalue="myconvo"><a href="https://forums.example.com/messenger/"><span data-role="folderName">Inbox</span></a></li> <li data-ipsmenuvalue="0"><a href="https://forums.example.com/messenger/?folder=0"><span data-role="folderName">Folder One</span></a></li> <li data-ipsmenuvalue="2"><a href="https://forums.example.com/messenger/?folder=2"><span data-role="folderName">Folder Three</span></a></li> <li data-ipsmenuvalue="4"><a href="https://forums.example.com/messenger/?folder=4"><span data-role="folderName">Folder Five</span></a></li> <li><a>Add Folder</a></li> </ul> The folder number for "Folder Five" didn't change! So I was moved forward under the assumption these integers correlated to account-specific folder IDs. My folder issues only appeared while I was trying to move messages with the "Move conversations" dialog accessible when using the message list check boxes. Let's see what the dialog drop-down thinks those folder numbers should be. <select name="move_message_to"> <option value="myconvo" selected>Inbox</option> <option value="0">Folder One</option> <option value="1">Folder Three</option> <option value="2">Folder Five</option> </select> There's our issue! The dialog is re-indexing our folder numbers instead of using the correct number found everywhere else. Moving messages to "Inbox" or "Folder One" always worked because the folder ID was correct for those two. So that's our problem but.. What's causing this? How can it be fixed? Why are the option values wrong? Since joining the Web Team (which has since been absorbed by our Data Systems S-Shop), I'm no stranger to poking around in the IPS code to track down minor issues that mostly stemmed from the server setup or IPS extensions. I began with inspecting the template's files to see if it was the one building the form incorrectly. With next to no leads, I remembered that this issue has existed through multiple IPS updates and changing themes between those updates, so this form must be getting generated by the IPS code. I decided to take a look at the dialog code once more to see WHERE does that form submission goes. <form action="https://forums.example.com/messenger/?page=1&amp;do=moveForm&amp;ids=12345" method="post" enctype="multipart/form-data"> <!-- ... --> </form> Thankfully, IPS's routing conventions make it easy to track down where that form submission is going. It's hitting a controller that's not explicitly listed here so it's likely in the "core" module and it's going to a function called "moveForm". A quick search of the "applications" and "system" directory for "function moveForm" yielded a controller named "_messenger" found within the core's "front/messaging" module. This "moveForm" function wasn't particularly complex and I quickly found a "select" field with the name of "move_message_to" that we saw in our dialog HTML - I think we have a match! <?php ... class _messenger extends \IPS\Content\Controller { ... protected function moveForm() { ... $folders = json_decode( \IPS\Member::loggedIn()->pconversation_filters, TRUE ) ?? array(); ... $form = new \IPS\Helpers\Form; $form->add( new \IPS\Helpers\Form\Select( 'move_message_to', NULL, FALSE, array( 'options' => array_merge( array( 'myconvo' => \IPS\Member::loggedIn()->language()->addToStack('inbox') ), $folders ), 'parse' => 'normal' ) ) ); ... } } I was able to quickly see that there is a list of folders attached to my account. I brought out the oldest debugging trick in the PHP developer book and I injected a "var_dump($folders);" momentarily so I could see the structure of that data. <?php $folders = ...; ... var_dump($folders); // Outputs: array(3) { [0]=> string(10) "Folder One" [2]=> string(12) "Folder Three" [4]=> string(11) "Folder Five" } So from this, we can see that the folder numbers are in tact. So it must be related to the form generator. After years of developing in PHP (and a good portion of my time debugging because it's honestly a crappy developer experience), a particular piece of code dealing with the array of folders caught my eye. <?php ... array_merge( array( 'myconvo' => \IPS\Member::loggedIn()->language()->addToStack('inbox') ), $folders ) ... That was it! But to make sure we are on the same page as to WHY the "array_merge" is the problem, let's take a look at the PHP docs for that function. The last sentence is exactly what is happening to our folders. In PHP, all keys are implicitly converted to integers unless it is a string not representing a decimal integer; in addition, PHP maintains an internal iterator to track the ordering of array items. In our case, our array of folders has numeric keys and they are being renumbered starting from zero as they are appended to the initial array that contains the default "Inbox" option. <?php // Example from the PHP Manual - https://www.php.net/manual/en/language.types.array.php $array = array( 1 => "a", "1" => "b", 1.5 => "c", true => "d", ); var_dump($array); // Outputs: array(1) { [1]=> string(1) "d" } How to we fix it? Merging two arrays in PHP when you want to maintain the key values is very trivial. <?php ... // First, we start with our first array that has the "Inbox" option $moveOptions = array ( 'myconvo' => \IPS\Member::loggedIn()->language()->addToStack('inbox') ); // Next, we loop over our list of folders, adding them to the array and maintaining their key value foreach ($folders as $id => $name) { $moveOptions[$id] = $name; } // Finally, we supply our new $moveOptions array in place of the array_merge $form->add( new \IPS\Helpers\Form\Select( 'move_message_to', NULL, FALSE, array( 'options' => $moveOptions, 'parse' => 'normal' ) ) ); ... A quick inspect of the dialog HTML and a test move of a message shows that issue has been fixed! <select name="move_message_to"> <option value="myconvo" selected>Inbox</option> <option value="0">Folder One</option> <option value="2">Folder Three</option> <option value="4">Folder Five</option> <option value="69">Winning Moments</option> </select> Conclusion Don't use PHP unless you have to because of some sort of hosting or compatibility reason - reconsider.
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.