We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 16430
    • 217 Posts
    Hi,
    I am wondering how to create a button on resource page, that would add resource ID to a logged user extended field (Login extra). So it can be used as a favourite page for each logged user and those page can be displayed using getresources.

    Any tips?
      • 9207 ☆ A M B ☆
      • 2,475 Posts
      The easiest way to do this would be via an HTML form and a Snippet (you could improve the UX by using an Ajax form submission, but that's harder to write). Something like this in your page or template:

      [[!saveFavorite]]
      <form action="[[~[[*id]]]]" method="post">
          <input type="hidden" name="favorite_page" value="[[*id]]" />
          <input type="submit" value="Save This Page as My Favorite Page" />
      </form>


      Then in your "saveFavorite" Snippet (untested):

      <?php
      if (!empty($_POST) && isset($_POST['favorite_page'])) {
          if (!$modx->user) {
              return; // no user logged in
          }
          // Get the user's extended fields
          $profile = $modx->user->getOne('Profile');
          $fields = $profile->get('extended');
          $fields['Favorite Page'] = (int) $_POST['favorite_page'];
          $profile->set('extended',$fields);
          $profile->save();
      }
      ?>
      


      See http://rtfm.modx.com/display/revolution20/Users

      For normal forms, you could skip the whole "favorite_page" thing as a hidden field and instead just read the value from the $modx object, but the above example would work via an Ajax submit.
        • 16430
        • 217 Posts
        Thaht looks good, thank you.
        But I want also have a opposite function of this button to "Remove from Favorites" once the form is submited or in case this page is already in favorites.
          • 9207 ☆ A M B ☆
          • 2,475 Posts
          Is it a single page? Or a list of favorites? The above outlines storage of a scalar (single) value. You'd have to rework it to store an array.

          To remove an item, you'd just blank out the value and save. Change this line:

          $fields['Favorite Page'] = '';
            • 16430
            • 217 Posts
            Ok I modified the code to this:
            Snippet saveFavorites:
            <?php
            if (!$modx->user) {
                    return; // no user logged in
                }
            	$id = $modx->resource->get('id'); //current id
                // Get the user's extended fields
                $profile = $modx->user->getOne('Profile');
                $fields = $profile->get('extended');
            	$fav_field = explode(",", $fields['Favorite Page']); // change string to array
            	$sent_id = (int) $_POST['favorite_page'];
                for($i = 0; $i < count($fav_field); ++$i) 
                  if ($fav_field[$i] == $id) {  // if found in array 
            	   if ($sent_id == $id) { 
            	      // if clicked to form button
            	    // foreach($sent_id as $k)  unset($fav_field[$k]);// remove sent id from array
                     foreach (array_keys($fav_field, $sent_id) as $key) unset($fav_field[$key]);
            
            		 $modx->setPlaceholder('FavPH','Add to Favorites'); // change placeholder text
                     $fields['Favorite Page'] = implode(",", $fav_field); //put the rest back in field
            		 $profile->set('extended',$fields);
                     $profile->save();
            		 return;
            		 }
            	   $modx->setPlaceholder('FavPH','Remove from Favorites'); // change placeholder text if already in field but button not clicked
            	   return;
            
            
            	  }
            	   //document not yet added to field
                 if (empty($sent_id)) {
                     $modx->setPlaceholder('FavPH','Add to Favorites');
            	     return; 
                     }
            	 else array_push($fav_field, $sent_id); //else add at the end of array
            	 $fields['Favorite Page'] = implode(",", $fav_field); //put the rest back in field
            	 $profile->set('extended',$fields);
                 $profile->save();
            	 $modx->setPlaceholder('FavPH','Remove from Favorites');

            And on page:
              [[!saveFavorite]]
            <form action="[[~[[*id]]]]" method="post">
                <input type="hidden" name="favorite_page" value="[[*id]]" />
                <input type="submit" value="[[+FavPH]]" />
            </form>


            Can you please check if this is correct, secure and optimized code? I am not that strong in PHP. Thanks.

            Update: Found a bug. If no user is logged into manager, page returns error :-/ [ed. note: kudykam last edited this post 13 years, 7 months ago.]
              • 9207 ☆ A M B ☆
              • 2,475 Posts
              Yes, a user would have to be logged in for this to work. You can wrap this line with an if-statement:

              $profile = $modx->user->getOne('Profile');


              e.g.

              if ($modx->user) {
                    //... logged in...
              }
              
                • 36924 ☆ A M B ☆
                • 298 Posts
                I'm interested in the final result of this will be interesting. What if you decide to limit the number of favourites users can have on thier profile to, say 10?

                kudykam were you able to make progress?
                  • 16430
                  • 217 Posts
                  Updated version of saveFavorites snippet:


                   [[!saveFavorite]]
                    <form action="[[~[[*id]]]]" method="post">
                      <input type="hidden" name="favorite_page" value="[[*id]]" />
                      <input type="submit" name="fav_submit" [[+FavPH]] />
                    </form>


                  <?php
                  $modx->setPlaceholder('FavPH','class="fav-star" title="Pleas log in" value="Add to favorites" ');
                  $id = $modx->resource->get('id'); //current id
                  $sent_id = (int) $_POST['favorite_page'];
                  
                  if ($modx->user->hasSessionContext($modx->context->get('key'))) { 
                     
                   
                  // after login
                   
                  
                      // Get the user's extended fields
                      $profile = $modx->user->getOne('Profile');
                      $fields = $profile->get('extended');
                    	$fav_field = explode(",", $fields['Favorite Page']); // change string to array
                  	
                      for($i = 0; $i < count($fav_field); ++$i) 
                        if ($fav_field[$i] == $id) {  // if found in array 
                  	   if ($sent_id == $id) { 
                  	      // if clicked to form button 
                  	    
                           foreach (array_keys($fav_field, $sent_id) as $key) unset($fav_field[$key]);
                  
                  		 $modx->setPlaceholder('FavPH','class="fav-star" title="Add to favorites" value="Add to favorites" '); // change placeholder text
                           $fields['Favorite Page'] = implode(",", $fav_field); //put the rest back in field
                  		 $profile->set('extended',$fields);
                           $profile->save();
                  		 return; 
                  		 }
                  	   $modx->setPlaceholder('FavPH',' class="fav-star-selected" title="Remove from favorites" value="Remove from favorites" '); // change placeholder text if already in field but button not clicked
                  	   return;
                  
                  
                  	  }
                  	   //document not yet added to field
                       if (empty($sent_id)) {
                           $modx->setPlaceholder('FavPH',' class="fav-star" title="Add to favorites" value="Add to favorites"');
                  	     return; 
                           }
                  	 else array_push($fav_field, $sent_id); //else add at the end of array
                  	 $fields['Favorite Page'] = implode(",", $fav_field); //put the rest back in field
                  	 $profile->set('extended',$fields);
                       $profile->save();
                  	 $modx->setPlaceholder('FavPH',' class="fav-star-selected" title="Remove from favorites" value="Remove from favorites" ');
                     return;
                   }
                  
                  if ($sent_id == $id) {               // redirect to login PAGE 57
                       $url = $modx->makeUrl(57);
                       $modx->sendRedirect($url);
                       }
                  
                  return;


                  Snippet needs some adjustment!
                  User Extended filed has name: Favorite Page
                  Change redirect page id

                  Limiting number of favorites should not be difficult...
                    • 36924 ☆ A M B ☆
                    • 298 Posts
                    I created the snippet and added a custom field to my register page and change the redirect page id asap.

                    First I lost the previous working section of the site where getResource brings related pages together (that section is now blank).
                    Secondly, the submit button comes up as "Submit Query", rather than the "Add to favorites" and simply reloads the page and no further behaviour like actual submit.


                    kudykam, Did this actually work for you?
                      • 36924 ☆ A M B ☆
                      • 298 Posts
                      My skill is still in the procedural era. My current task has two features to go. And I'm going to need lots of help.

                      On the first, I aim to achieve this:
                      Users will add pages as their favorite (in my "add to playlist"). And can (as the code above suggest) remove favorites as well. They can only have 14 favorites pages (beyond this they are prompted to remove to be able to add more). Now this favorite pages (using either getRelated or getResources) will be available on their profile pages as well (there they can also remove a page from the list but not add). To add they must be on the page they wish to add.