1. Fabrik 3.7 is now available. This version contains critical security updates, please update as soon as possible. Please remember to backup your site before updating, we also recommend testing your updates on development sites if possible.
  2. We had to restore the site around midday (CST) on Wed 7/26 from a backup approximately 8 hours old. So a few posts in the forums were lost. You may want to check to see if you need to re-post anything.
  3. The release of Fabrik for J! 3.8 is not yet ready. Do not update your sites to J! 3.8 until this notice is removed.

CommunityBuilder - Code Snippets

Mar 11, 2015
CommunityBuilder - Code Snippets

  • Picklist Element Validation Plugin(top)

    PHP:
    function array_find($needle, $haystack)
    {
      foreach ($haystack as $key => $item)
      {
          if (strpos($item, $needle) !== FALSE)
          {
            return $key;
            break;
          }
      }
      return false;
    }
    $formData = $formModel->formData;
    // Get the list of interests and which ones are additionsadditions
    $interests = json_decode($formData['member_interests___member_interests']);
    $additions = json_decode($formData['member_interests___member_interests_additions']);
    // If there are no additions just return
    if ( !is_array($additions) | count($additions) == 0)
      return true;
     
    // get the list of existing interests
    $db  = JFactory::getDBO();
    $query = $db->getQuery(true);
    $query
      ->select("params")
      ->from("#__fabrik_elements")
        ->where("name='member_interests'");
    $db->setQuery($query);
    $params = json_decode(htmlspecialchars_decode($db->loadResult()));
    $existing = $params->sub_options->sub_values;
    asort($existing);
     
    // Go through each addition, change to uppercase words and set the value to a single
    // word by replacing spaces, dashes and slashes with underscores. While we are at it
    // remove the additions from the interests so we can ensure no duplications
    foreach ($additions as $key => $addition) {
      unset($interests[array_search($additions[$key]->val, $interests)]);
      $additions[$key]->val = str_replace(array(" ", "-", "/"), "_", ucwords($additions[$key]->val));
      $additions[$key]->label = ucwords($additions[$key]->label);
    }
     
    // Now go again to ensure the addition isn't using a name that already exists
    // and that the member hasn't tried to add the addition twice
    // a name exists when the new name is the same as a part of an exiting name
    // examples are a new interest of Golf when Golfing is already an interest
    // or new Games when Board Games exists
    $failures = array();
    foreach ($additions as $key => $addition) {
      if (array_find($addition->val, $existing) !== false ) {
            // The interest word is already in an existing interest
            $failures[] = $addition;    // Add it to the failures list
            unset($additions[$key]);    // Remove it from the additions list
            continue;
      }
      // It isn't in the existing list, check that the name is not used twice in the additions
      foreach ($additions as $aKey => $add) {
        if ($aKey == $key) continue;    // Don't check against itself
        if (strpos($add->val, $addition->val) !== false) {
            // The interest word is already in an existing addition
            $failures[] = $addition;    // Add it to the failures list
            unset($additions[$key]);    // Remove it from the additions list
            continue;
        }
      }
    }
    // And one last test, make sure that the new interest doesn't clash with an existing interest
    // in this case we check against a new value of Board Games when Games already exists
    foreach ($existing as $exists) {
        foreach ($additions as $key => $addition) {
            if ( strpos($addition->val, $exists ) !== false ) {
                // an existing interest contains the new addition word
                $failures[] = $addition;    // Add it to the failures list
                unset($additions[$key]);    // Remove it from the additions list
                continue;
            }
        }
    }
    // For failures
    if ( count($failures) > 0 ) {
        $text = "";
     
        foreach ($failures as $key => $failure) {
            if ($key>0)
                $text .= ", ";
            $text .= $failure->label;
        }
     
        if (count($failures) == 1 )
            $message = "Your addition $text is invalid.";
        else
            $message = "Your additions $text are invalid.";
        $message .= " The name exists as part of an existing interest or an existing interest is contained in this addition.<br>Please select another name";
        $this->setMessage($message);
        return false;
    }
    return true;

    Form onBeforeProcess Plugin(top)

    PHP:
    /* code to take the picklist and save it to CB */
    $formData = $formModel->formData;
    /* Convert things like &amp; to correct characters, decode into an array and drop empty elements */
    $interests = $formData['member_interests___member_interests'];
    $additions = json_decode(htmlspecialchars_decode($formData['member_interests___member_interests_additions']));
    // If there are no additions just return
    if ( !is_array($additions) | count($additions) == 0)
      return true;
     
    // Go through each addition, change to uppercase words and set the value to a single
    // word by replacing spaces, dashes and slashes with underscores.
    foreach ($additions as $key => $addition) {
      // find the addition in the interests array
      $iKey = array_search($addition->val, $interests);
      // set the value to a ucword unique string, and ucword the label
      $additions[$key]->val = str_replace(array(" ", "-", "/"), "_", ucwords($additions[$key]->val));
      $additions[$key]->label = ucwords($additions[$key]->label);
      // ucword the interest
      $interests[$iKey] = $additions[$key]->val;
    }
    // sort alphanumerically
    sort($interests, SORT_STRING | SORT_FLAG_CASE);
     
    // First, make sure the addition is not in twice
    foreach ($interests as $key =>$interest) {
      $tmp = $interests;
      unset($tmp[$key]);
        if (in_array($interest, $tmp))
            unset($interests[$key]);    // Duplicate
    }
    /* The following validates whether an interest is leftover in the formData as a result
    * of an addition validation failure. There is a bug in the picklist that leaves the
    * addition in the interests list. Fabrik knows about it but it is a big job to
    * correct. I can dix it simply here by validating that the interest exists either
    * in the list of existing interests or in the additions.
    */

    // get the list of existing interests
    $db    = JFactory::getDBO();
    $query = $db->getQuery(true);
    $query
        ->select("params")
        ->from("#__fabrik_elements")
        ->where("name='member_interests'");
    $db->setQuery($query);
    $params = json_decode(htmlspecialchars_decode($db->loadResult()));
    $existing = $params->sub_options->sub_values;
    asort($existing);
    foreach ($interests as $key => $interest ) {
      if ( strlen($interest) == 0 ) continue;
      if (!in_array($interest, $existing) ) {
        foreach($additions as $addition) {
            if ($interest == $addition->val)
                continue 2;
        }
        unset($interests[$key]);    // didn't find it, drop it
      }
    }
    // encode the both
    $interests_raw = json_encode(array_values($interests));
    $additions = json_encode($additions);
    // Put the values back into the form
    $formModel->updateFormData('member_interests___member_interests', array_values($interests));
    $formModel->updateFormData('member_interests___member_interests_raw', $interests_raw);
    $formModel->updateFormData('member_interests___member_interests_additions', $additions);

    Redirect Article(top)

    PHP:
    {source}<?php
    $jinput = JFactory::getApplication()->input;
    $id = $jinput->get('member_interests___id');
     
    $db = JFactory::getDBO();
    $user = JFactory::getUser();
    $query = $db->getQuery(true);
    $query
    ->select('mi.member_interests')
    ->from('member_interests AS mi')
    ->where("mi.id=$id");
    $db->setQuery($query);
    /* Convert things like &amp; to correct characters, decode into an array and drop empty elements */
    $values = array_filter(json_decode(htmlspecialchars_decode ($db->loadResult())));
    // sort alphanumerically
    sort($values, SORT_STRING | SORT_FLAG_CASE);
     
    /* Now get the labels associated with these values */
    $query = $db->getQuery(true);
    $query
    ->select("params")
    ->from("#__fabrik_elements")
    ->where("name='member_interests'");
    $db->setQuery($query);
    $options = json_decode($db->loadResult())->sub_options;
    $labels = array();
    foreach($values as $value) {
    $labels[] = $options->sub_labels[array_search($value, $options->sub_values)];
    }
     
    // Get labels and values back into strings
    $labels = implode(", ", $labels);
    $values = implode(", ", $values);
     
    // now update the cb database, it uses the values for searching
    $query = $db->getQuery(true);
    $query
    ->update('#__comprofiler')
    ->set('cb_member_interests = ' . $db->quote($values))
    ->where('user_id=' . $user->id);
    $db->setQuery($query);
    $db->execute();
     
    // Now update the form data,
    // cb_member_interests is the cb data and is the values and is hidden
    // cb_member_interests_disp is what the user sees and is the labels
    echo '<script language="javascript" type="text/javascript">'
    . 'el = window.parent.document.getElementById("cb_member_interests");'
    . 'el.value = "' . $values . '";'
    . 'el = window.parent.document.getElementById("cb_member_interests_disp");'
    . 'el.value = "' . $labels . '";'
    . 'parent.jQuery.colorbox.close();'
    . '</script>';
    ?>{/source}