Isuniquevalue with 2 conditions in 2 tables

Good Morning:)
As I said in previous thread ... the validation "isuniquevalue" is great.
Now, I'm trying to control 2 fields ... and I just did not get it.
I have this code in the section "condition", which works perfectly ... and that controls that in the table there is only a single field "habitatge" of a "user"

if ('{gpexpedient___gp_exp_tipusimmoble}' == 'habitatge')
{
return true;
}
else {
return false;
}

upload_2018-3-9_8-9-54.png

I need that I could also control a databasejoin element, which points to another table ... but with the same values ...o_O
I've tried with this code adding an "AND" ... that I understand is correct ... but maybe, I'm asking something that fabrik and the element "isuniquevalue" can not assume ... or maybe I'm doing something wrong ...
if ('{gpexpedient___gp_exp_tipusimmoble}' == 'habitatge' and '{gphabitatge___gp_hab_tipusinmoble}' == 'habitatge')
{
return true;
}
else {
return false;
}


Another option ... if it were not possible ... and at the same time it's simpler ...
It would be to add a php code in the database that compares the value of the "habitatge" and unique dropdown with the value of the table "gp_hab_tipusinmoble} '==' habitatge '" and will ONLY save the form if these 2 selected fields are equal ...

I hope you have explained me well ...Let's see if you can help me with this element "isuniquevalue" ... I'm running out of ideas ... :( and I've been with this dilemma for several days ...
:)Thank you:)
 

Attachments

  • upload_2018-3-9_8-3-54.png
    upload_2018-3-9_8-3-54.png
    61.4 KB · Views: 45
Have you tried the 'areuniquevalues' validation, which allows for testing multiple values for uniqueness?

It's not part of the core, you have to either download and install the ZIP, or discover/install/enable it (in J!'s extension manager) if you've done a full github update (in which case you have the code, it just needs installing).

-- hugh
 
@albertotactik - I am not sure I have really understood what you are trying to achieve, but I am not sure that you are approaching it correctly.

As I understand it the Condition field defines when the isuniquevalue validation runs. In this case it seems that for the first example you want to ensure that this field is unique only if the field gpexpedient___gp_exp_tipusimmoble on your screen is set to the value 'habitatge' and you are not worried about this field being unique if the value is not 'habitatge'. I am unclear whether the element this isuniquevalue validation is on is gpexpedient___gp_exp_tipusimmoble or a different element, but if it is the same element then I guess this would indeed have the effect of allowing only one value of 'habitage' in the database in total not per user. However you might not have spotted this if you have not tested it with two different users.

If you want each user to be able to use 'habitage' only once, then as Hugh has indicated, you need the areuniquevalues validation plugin, and you need to:

1. Store the userid in your table too (even if hidden); and
2. Set the areuniquevalues on one or both of the gp_exp_tipusimmoble and userid fields

Looking at your second point, I am having difficulty in understanding what you are trying to achieve regarding the databasejoin fields. Perhaps if you could give us details of the databasejoin field you are using, we might have a better chance of understanding what you are trying to achieve and then to help you.
 
Have you tried the 'areuniquevalues' validation, which allows for testing multiple values for uniqueness?

It's not part of the core, you have to either download and install the ZIP, or discover/install/enable it (in J!'s extension manager) if you've done a full github update (in which case you have the code, it just needs installing).

-- hugh
good...
I've tried the areuniquevalues option ... and I would miss the "condition" option that does have the "uniquevalues" validation.
I try to explain myself better in the next post below
Thank you!!!!!
 
Good Morning.
First of all ... thanks for the interest and attention.
I try to explain better the dilemma that I have, with an image.
There is a "expedient" form and it contains 3 elements
upload_2018-3-11_9-53-21.png
a) Element "solicitant" that is a databasejoin of the "solicitant" table
b) Element "tipusinmoble" that is a dropdown with the values (habitatge, pla?a aparcament, local, solar and traster)
c) Element "carrer immoble" that is a databasejoin of the "habitatge" table that has the same values (habitatge, pla?a aparcament, local, solar and traster)
that the "tipusinmoble" element of option b) ... and visualize it with 3 fields with the "Or Concat label" option
upload_2018-3-11_9-46-54.png
I need the following validation and with some condition ...
1) The value "tipus d'inmoble" must always be equal to the value of "carrer immoble"

2) Albert or Peter (sol.licitant) can never have 2 "habitatges" ... but they can have 1 habitatge + 2 traster + 2 local

I hope the explanation is a little clearer ...
A thousand thanks for the collaboration and for giving me hope:):):):)
 
Ok - so it seems to me that you need to do two or three things:

1. Make sure that for each value of Solicitant there is at most one tipusimoble that is "habitage". For this you need the areuniquevalues plugin because you are trying to ensure that the combination of two fields are unique. However as you pointed out the areuniquevalues plugin does not have the condition (or case insensitive search) capability of the isuniquevalue.

So I guess there are a two ways to achieve this:

a. Enhance the areuniquevalues plugin to include the condition (and case insensitive search) capabilities of the isuniquevalues plugin by copying some of the code across. To ensure that your changes survive an update from Github, you would need to submit these changes as a PR (and for Hugh to merge it).

b. Convert the tipusdimoble to a databasejoin dropdown (creating a reference table to hold the values) and then use the WHERE clause with a subquery to exclude the habitage option if the database already contains the solicitant/tipusdimoble combination. You would need to enable ajax for this as well so that the list is repopulated if the solicitant field is changed.

2. It seems to me that the best way of making sure that the carrerinmoble field matches the tipusinmoble is to ensure that the dropdown only includes values that match tipusinmoble in the first place.

I am not an expert on cascadingdropdown element, but this seems to be the sort of situation this is designed for. Alternatively, you can certainly do this with databasejoin with ajax on and a carefully crafted where clause but this is likely to be harder to work out.

Hope this helps.
 

a. Enhance the areuniquevalues plugin to include the condition (and case insensitive search) capabilities of the isuniquevalues plugin by copying some of the code across. To ensure that your changes survive an update from Github, you would need to submit these changes as a PR (and for Hugh to merge it).

I added this code right on line 23 in the fields.xml file that is inside the forms directory. It is right??
visually ... it looks like it's fine ...
but I think the "isuniquevalue.php" file will be more difficult, I can do it well ...
upload_2018-3-12_14-12-17.png
<field name="isuniquevalue-validation_condition"
type="fabrikeditor"
mode="php"
description="PLG_VALIDATIONRULE_ISUNIQUE_CONDITION_DESC"
label="PLG_VALIDATIONRULE_ISUNIQUE_CONDITION_LABEL"
repeat="true" />
<field name="isuniquevalue-caseinsensitive"
type="radio"
default="0"
class="btn-group"
label="PLG_VALIDATIONRULE_ISUNIQUE_CASE_SENSETIVE_LABEL"
repeat="true">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>


Then I notice that there is a file called "isuniquevalue.php" in the root of the plugin, which I imagine that I will have to copy part of the code ...
It would be enough to copy this 2 lines that contain the variable $cond:

$ cond = $ params-> get ('isuniquevalue-caseinsensitive') == 1? 'LIKE': '=';

$ query-> select ('COUNT (*)') -> from ($ db-> qn ($ lookupTable)) -> where ($ k. ''. $ cond. ''. $ data);


I have analyzed the code and I have a hard time interpreting it ...
Thanks for the patience and attention ...
 
This is a good start - copying the XML lines.

However:

1. You need to change the XML field names from isuniquevalue-validation_condition to areuniquevalues-condition and isuniquevalue-caseinsensitive to areuniquevalues-caseinsensitive

2. You really should change the language strings from ISUNIQUE to AREUNIQUE (and maybe correct SENSETIVE to SENSITIVE). Then you need to copy the lines from all the ISUNIQUE language files into the AREUNIQUE language files changing the id to match.

2. The code you are then looking to copy from isuniquevalue.php to areuniquevalues.php are the ones relating to the names of the fields i.e. isuniquevalue-validation_condition and isuniquevalue-caseinsensitive (changing the names again).

If you make these same changes in a PR on Github, I would be happy to review them for you.
 
This is a good start - copying the XML lines.

However:

1. You need to change the XML field names from isuniquevalue-validation_condition to areuniquevalues-condition and isuniquevalue-caseinsensitive to areuniquevalues-caseinsensitive

2. You really should change the language strings from ISUNIQUE to AREUNIQUE (and maybe correct SENSETIVE to SENSITIVE). Then you need to copy the lines from all the ISUNIQUE language files into the AREUNIQUE language files changing the id to match.

2. The code you are then looking to copy from isuniquevalue.php to areuniquevalues.php are the ones relating to the names of the fields i.e. isuniquevalue-validation_condition and isuniquevalue-caseinsensitive (changing the names again).

If you make these same changes in a PR on Github, I would be happy to review them for you.
Good Morning,
today I will try to see if I can continue and finish this update of "areuniquevalue" ...
It's going to be almost impossible for me ... since I find it hard to interpret code.
however ... I will try.

another option that I think could be interesting for me ... would be to buy the validation update "areuniquesvalue" with paragraph condition ...

what would it cost ... and how long would it take to have it?
thank you again ...
Alberto
 
Este es un buen comienzo: copiar las l?neas XML.
This is a good start - copying the XML lines.
However:
1. You need to change the XML field names from isuniquevalue-validation_condition to areuniquevalues-condition and isuniquevalue-caseinsensitive to areuniquevalues-caseinsensitive
2. You really should change the language strings from ISUNIQUE to AREUNIQUE (and maybe correct SENSETIVE to SENSITIVE). Then you need to copy the lines from all the ISUNIQUE language files into the AREUNIQUE language files changing the id to match.
2. The code you are then looking to copy from isuniquevalue.php to areuniquevalues.php are the ones relating to the names of the fields i.e. isuniquevalue-validation_condition and isuniquevalue-caseinsensitive (changing the names again).
If you make these same changes in a PR on Github, I would be happy to review them for you.

Good Morning...
I start with section 1)
I tried to follow directions ... and I think the file es-ES.plg_fabrik_validationrule_areuniquevalues.ini is already finished ...
I DO NOT attach a file because I know if it is the right thing or it is not allowed) I copy the code below this line:
if there was something wrong in this code ... tell me and I check it ... (thanks)

Code:
PLG_VALIDATIONRULE_AREUNIQUEVALUES_ERROR_LABEL="Mensaje de error"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_ERROR_DESC="Texto mostrado al lado del campo si la validaci?n falla"
PLG_VALIDATIONRULE_AREUNIQUE_CONDITION_LABEL="Condici?n"
PLG_VALIDATIONRULE_AREUNIQUE_CONDITION_DESC="C?digo PHP que devuelve true si la validaci?n es correcta"
PLG_VALIDATIONRULE_AREUNIQUE_CASE_SENSETIVE_LABEL="B?squeda ignorando may?sculas y min?sculas"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_LABEL="Elemento de comparaci?n adicional"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_DESC="Opcional: un elemento adicional que tambi?n debe tener un valor ?nico"

; PLG_FABRIK_OPTIONS="Options"
; PLG_FABRIK_VALIDATION_ICON_DESC="Bootstrap icon name (or image name for J2.5), leave off 'icon-' prefix. Shown in the form, next to validation explaination text"
; PLG_FABRIK_VALIDATION_ICON_LABEL="Icon"
;FRONT END
PLG_VALIDATIONRULE_AREUNIQUEVALUES_LABEL="El valor no puede haber sido grabado anteriormente"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_ADDITIONAL_LABEL="Este valor y el valor de '%s' no puede haber sido grabado anteriormente en la misma fila o registro"

Now I'm going to modify this file fields.xml and then the file areuniquevalues.php, as you indicate.
I hope that during today ... I can finish ...
Thanks for the cheering
 
Last edited by a moderator:
good!!
this would be the fields.xml file of the "areuniquevalue" validation
it is right.... ?? if it is correct ... I will modify the areuniquevalues.php

Code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<form>
    <fields addfieldpath="/administrator/components/com_fabrik/models/fields" name="params">
        <fieldset name="plg-validationrule-areuniquevalues">
            <field name="areuniquevalues-message"
                type="text"
                description="PLG_VALIDATIONRULE_AREUNIQUEVALUES_ERROR_DESC"
                label="PLG_VALIDATIONRULE_AREUNIQUEVALUES_ERROR_LABEL"
                repeat="true"
                size="30" />
              
            <field name="areuniquevalue-validation_condition"
                type="fabrikeditor"
                mode="php"
                description="PLG_VALIDATIONRULE_AREUNIQUE_CONDITION_DESC"
                label="PLG_VALIDATIONRULE_AREUNIQUE_CONDITION_LABEL"
                repeat="true" />

            <field name="areuniquevalue-caseinsensitive"
                type="radio"
                default="0"
                class="btn-group"
                label="PLG_VALIDATIONRULE_AREUNIQUE_CASE_SENSETIVE_LABEL"
                repeat="true">
                    <option value="0">JNO</option>
                    <option value="1">JYES</option>
            </field>

            <field name="areuniquevalues-otherfield"
                type="listfields"
                description="PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_DESC"
                label="PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_LABEL"
                repeat="true" />

            <field name="areuniquevalues-otherfield2"
                   type="listfields"
                   description="PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_DESC"
                   label="PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_LABEL"
                   repeat="true" />

            <field name="tip_text"
                   type="textarea"
                   repeat="true"
                   cols="30"
                   rows="3"
                   description="COM_FABRIK_VALIDATION_TIP_TEXT_DESC"
                   label="COM_FABRIK_VALIDATION_TIP_TEXT_LABEL"/>

            <field name="icon"
                   type="field"
                   repeat="true"
                   description="PLG_FABRIK_VALIDATION_ICON_DESC"
                   label="PLG_FABRIK_VALIDATION_ICON_LABEL" />
        
        </fieldset>
    </fields>
</form>
 
Last edited by a moderator:
I know what I said before, but for consistency can you make it as follows:
Code:
PLG_VALIDATIONRULE_AREUNIQUEVALUES_ERROR_LABEL="Mensaje de error"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_ERROR_DESC="Texto mostrado al lado del campo si la validaci?n falla"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_CONDITION_LABEL="Condici?n"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_CONDITION_DESC="C?digo PHP que devuelve true si la validaci?n es correcta"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_CASE_SENSITIVE_LABEL="B?squeda ignorando may?sculas y min?sculas"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_LABEL="Elemento de comparaci?n adicional"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_OTHER_FIELD_DESC="Opcional: un elemento adicional que tambi?n debe tener un valor ?nico"

; PLG_FABRIK_OPTIONS="Options"
; PLG_FABRIK_VALIDATION_ICON_DESC="Bootstrap icon name (or image name for J2.5), leave off 'icon-' prefix. Shown in the form, next to validation explaination text"
; PLG_FABRIK_VALIDATION_ICON_LABEL="Icon"
;FRONT END
PLG_VALIDATIONRULE_AREUNIQUEVALUES_LABEL="El valor no puede haber sido grabado anteriormente"
PLG_VALIDATIONRULE_AREUNIQUEVALUES_ADDITIONAL_LABEL="Este valor y el valor de '%s' no puede haber sido grabado anteriormente en la misma fila o registro"

You will also need to make the same changes in all the other languages which have translations in isuniquevalue when you do the PR. Sorry.
 
The XML looks fine except I would make:

<field name="areuniquevalue-validation_condition" be <field name="areuniquevalues-condition"
and
<field name="areuniquevalue-caseinsensitive" be <field name="areuniquevalues-caseinsensitive"
 
Hello,
I have added the lines of code that are blue and italic ...

I have doubts about whether I should have replaced some line of code ...
since I observe that there are 2 querys ... for example ..
If it was not right ... tell me and I look to correct, whatever it takes.
Thanks again...


PHP:
<?php

/**
* Are Unique values Validation Rule
*
* @package     Joomla.Plugin
* @subpackage  Fabrik.validationrule.areuniquevalues
* @copyright   Copyright (C) 2005-2013 fabrikar.com & Lieven Gryp - All rights reserved.
* @license     GNU/GPL http://www.gnu.org/copyleft/gpl.html
*/

// No direct access
defined('_JEXEC') or die('Restricted access');

// Require the abstract plugin class
require_once COM_FABRIK_FRONTEND . '/models/validation_rule.php';

/**
* Are Unique values Validation Rule
*
* @package     Joomla.Plugin
* @subpackage  Fabrik.validationrule.areuniquevalues
* @since       3.0
*/

class PlgFabrik_ValidationruleAreUniqueValues extends PlgFabrik_Validationrule

{
    /**
     * Plugin name
     *
     * @var string
     */

    protected $pluginName = 'areuniquevalues';

    /**
     * Validate the elements data against the rule
     *
     * @param   string $data          To check
     * @param   int    $repeatCounter Repeat group counter
     *
     * @return  bool  true if validation passes, false if fails
     */

    public function validate($data, $repeatCounter)

    {
        $input        = $this->app->input;
        $elementModel = $this->elementModel;

        // Could be a dropdown with multivalues

        if (is_array($data))
        {
            $data = implode('', $data);
        }
        $params     = $this->getParams();
        $element   =$elementModel->getElement();
        $listModel  = $elementModel->getlistModel();
        $table      = $listModel->getTable();
        $db          = $listModel->getDb();
    //$lookupTable = $db->qn($table->db_table_name);
       $data        = $db->q($data);
       $query       = $db->getQuery(true);
       $cond        = $params->get('areuniquevalues-caseinsensitive') == 1 ? 'LIKE' : '=';
       $secret      = $this->config->get('secret');
       $groupModel = $elementModel->getGroup();

   // if it's a join, get the joined table name

        if ($groupModel->isJoin())
        {
            $lookupTable = $groupModel->getJoinModel()->getJoin()->table_join;
        }

        else
        {
            $lookupTable = $table->db_table_name;
        }

        if ($elementModel->encryptMe())
        {
            $k = 'AES_DECRYPT(' . $element->name . ', ' . $db->q($secret) . ')';
        }

        else
        {
            $k = $db->qn($element->name);
        }

        $query->select('COUNT(*)')->from($db->qn($lookupTable))->where($k . ' ' . $cond . ' ' . $data);

        /*
         * $$$ hugh - need to check to see if we're editing a record, so we can exclude this record
         *
         * Need to figure out if this is a joined element, and set PK and 'rowid' accordingly
         *
         * NOTE - probably only works for non-repeat joins
         */

        if (!$groupModel->isJoin())
        {
            // not a join, just use rowid and normal pk

            $rowId = $input->get('rowid', '');
            $pk = $table->db_primary_key;
        }

        else
        {
            // join, so get the join's PK and value as rowid

            $pk = $groupModel->getJoinModel()->getForeignID();
            $rowId = $this->formModel->formData[$pk];
            $pk = $groupModel->getJoinModel()->getForeignID('.');
        }

        if (!empty($rowId))
        {
            $query->where(FabrikString::safeQuoteName($pk) . ' != ' . $db->q($rowId));
      }
        $db->setQuery($query);
        $c = $db->loadResult();
        return ($c === '0') ? true : false;
    }
}
        $otherField = $params->get('areuniquevalues-otherfield', '');

        if ((int) $otherField !== 0)

        {
            $otherElementModel = $this->getOtherElement();
            $otherFullName     = $otherElementModel->getFullName(true, false);
            $otherField        = $otherElementModel->getFullName(false, false);
        }

        else

        {
            // Old fabrik 2.x params stored element name as a string

            $otherFullName = $table->db_table_name . '___' . $otherField;
        }

        $otherField2 = $params->get('areuniquevalues-otherfield2', '');

        if ((int) $otherField2 !== 0)
        {
            $otherElementModel2 = $this->getOtherElement('2');
            $otherFullName2     = $otherElementModel2->getFullName(true, false);
            $otherField2        = $otherElementModel2->getFullName(false, false);
        }

        else
        {
            // Old fabrik 2.x params stored element name as a string
            $otherFullName2 = $table->db_table_name . '___' . $otherField;
        }

        $db          = $listModel->getDb();
        $lookupTable = $db->qn($table->db_table_name);
        $data        = $db->q($data);
        $query       = $db->getQuery(true);
        $query->select('COUNT(*)')->from($lookupTable)->where($db->qn($elementModel->getFullName(false, false)) . ' = ' . $data);

        $listModel->buildQueryJoin($query);

        if (!empty($otherField))

        {
            // $$$ the array thing needs fixing, for now just grab 0
            $formData = $elementModel->getForm()->formData;
            $v        = FArrayHelper::getValue($formData, $otherFullName . '_raw', FArrayHelper::getValue($formData, $otherFullName, ''));

            if (is_array($v))
            {
                $v = FArrayHelper::getValue($v, 0, '');
            }
            $query->where($db->qn($otherField) . ' = ' . $db->quote($v));
        }

        if (!empty($otherField2))
        {
            // $$$ the array thing needs fixing, for now just grab 0
            $formData = $elementModel->getForm()->formData;
            $v        = FArrayHelper::getValue($formData, $otherFullName2 . '_raw', FArrayHelper::getValue($formData, $otherFullName2, ''));

            if (is_array($v))
            {
                $v = FArrayHelper::getValue($v, 0, '');
            }
            $query->where($db->qn($otherField2) . ' = ' . $db->quote($v));
        }

        /* $$$ hugh - need to check to see if we're editing a record, otherwise
         * will fail 'cos it finds the original record (assuming this element hasn't changed)
         * @TODO - is there a better way getting the rowid?  What if this is form a joined table?
         */

        $rowId = $input->get('rowid');

        if (!empty($rowId))
        {
            $query->where($table->db_primary_key . ' != ' . $db->q($rowId));
        }

        $db->setQuery($query);
        $c = $db->loadResult();
        return ($c == 0) ? true : false;
    }

    /**
     * Gets the other element model to compare this plugins element data against
     *
     * @return    object element model
     */

    private function getOtherElement($suffix = '')
    {
        $params     = $this->getParams();
        $otherField = $params->get('areuniquevalues-otherfield' . $suffix);
        return FabrikWorker::getPluginManager()->getElementPlugin($otherField);
    }

    /**
     * Gets the hover/alt text that appears over the validation rule icon in the form
     *
     * @return    string    label
     */
    protected function getLabel()

    {
        $params            = $this->getParams();
        $otherField        = $params->get('areuniquevalues-otherfield');
        $otherField2        = $params->get('areuniquevalues-otherfield2');
        $tipText           = $params->get('tip_text', '');

        if (empty($tipText) && ((int) $otherField !== 0 || (int) $otherField2 !== 0))
        {
            $labels = array();
            if ((int)$otherField !== 0)
            {
                $otherElementModel = $this->getOtherElement();
                $labels[] = $otherElementModel->getElement()->label;
            }

            if ((int)$otherField2 !== 0)
            {
                $otherElementModel = $this->getOtherElement('2');
                $labels[] = $otherElementModel->getElement()->label;
            }

            $labels = implode(' ' . strtolower(JText::_('COM_FABRIK_AND')) . ' ', $labels);
            return JText::sprintf('PLG_VALIDATIONRULE_AREUNIQUEVALUES_ADDITIONAL_LABEL', $labels);
        }

        else
        {
            return parent::getLabel();
        }
    }
}
 
Last edited:
uyy
italics and blue color disappeared ... for a better identification of the changes ...
I imagine that it will have been to introduce it as a window to insert PHP code.
 
/**
* Are Unique values Validation Rule
*
* @package Joomla.Plugin
* @subpackage Fabrik.validationrule.areuniquevalues
* @copyright Copyright (C) 2005-2013 fabrikar.com & Lieven Gryp - All rights reserved.
* @license GNU/GPL http://www.gnu.org/copyleft/gpl.html
*/

// No direct access
defined('_JEXEC') or die('Restricted access');

// Require the abstract plugin class

require_once COM_FABRIK_FRONTEND . '/models/validation_rule.php';

/**

* Are Unique values Validation Rule
*
* @package Joomla.Plugin
* @subpackage Fabrik.validationrule.areuniquevalues
* @since 3.0
*/
class PlgFabrik_ValidationruleAreUniqueValues extends PlgFabrik_Validationrule

{
/**
* Plugin name
*
* @var string
*/

protected $pluginName = 'areuniquevalues';
/**
* Validate the elements data against the rule
*
* @param string $data To check
* @param int $repeatCounter Repeat group counter
*
* @return bool true if validation passes, false if fails
*/

public function validate($data, $repeatCounter)
{
$input = $this->app->input;
$elementModel = $this->elementModel;

// Could be a dropdown with multivalues

if (is_array($data))
{
$data = implode('', $data);
}

$params = $this->getParams();
$element = $elementModel->getElement();
$listModel = $elementModel->getlistModel();
$table = $listModel->getTable();
$db = $listModel->getDb();
//$lookupTable = $db->qn($table->db_table_name);
$data = $db->q($data);
$query = $db->getQuery(true);
$cond = $params->get('areuniquevalues-caseinsensitive') == 1 ? 'LIKE' : '=';
$secret = $this->config->get('secret');
$groupModel = $elementModel->getGroup();
// if it's a join, get the joined table name


if ($groupModel->isJoin())
{
$lookupTable = $groupModel->getJoinModel()->getJoin()->table_join;
}

else
{
$lookupTable = $table->db_table_name;
}

if ($elementModel->encryptMe())
{
$k = 'AES_DECRYPT(' . $element->name . ', ' . $db->q($secret) . ')';
}

else
{
$k = $db->qn($element->name);
}

$query->select('COUNT(*)')->from($db->qn($lookupTable))->where($k . ' ' . $cond . ' ' . $data);
/*
* $$$ hugh - need to check to see if we're editing a record, so we can exclude this record
*
* Need to figure out if this is a joined element, and set PK and 'rowid' accordingly
*
* NOTE - probably only works for non-repeat joins
*/

if (!$groupModel->isJoin())
{
// not a join, just use rowid and normal pk
$rowId = $input->get('rowid', '');
$pk = $table->db_primary_key;
}

else
{
// join, so get the join's PK and value as rowid
$pk = $groupModel->getJoinModel()->getForeignID();
$rowId = $this->formModel->formData[$pk];
$pk = $groupModel->getJoinModel()->getForeignID('.');
}

if (!empty($rowId))
{
$query->where(FabrikString::safeQuoteName($pk) . ' != ' . $db->q($rowId));
}

$db->setQuery($query);
$c = $db->loadResult();

return ($c === '0') ? true : false;
}
}


$otherField = $params->get('areuniquevalues-otherfield', '');

if ((int) $otherField !== 0)
{
$otherElementModel = $this->getOtherElement();
$otherFullName = $otherElementModel->getFullName(true, false);
$otherField = $otherElementModel->getFullName(false, false);
}

else
{
// Old fabrik 2.x params stored element name as a string
$otherFullName = $table->db_table_name . '___' . $otherField;
}

$otherField2 = $params->get('areuniquevalues-otherfield2', '');

if ((int) $otherField2 !== 0)
{
$otherElementModel2 = $this->getOtherElement('2');
$otherFullName2 = $otherElementModel2->getFullName(true, false);
$otherField2 = $otherElementModel2->getFullName(false, false);
}

else

{
// Old fabrik 2.x params stored element name as a string
$otherFullName2 = $table->db_table_name . '___' . $otherField;
}


$db = $listModel->getDb();
$lookupTable = $db->qn($table->db_table_name);
$data = $db->q($data);
$query = $db->getQuery(true);
$query->select('COUNT(*)')->from($lookupTable)->where($db->qn($elementModel->getFullName(false, false)) . ' = ' . $data);

$listModel->buildQueryJoin($query);

if (!empty($otherField))
{
// $$$ the array thing needs fixing, for now just grab 0
$formData = $elementModel->getForm()->formData;
$v = FArrayHelper::getValue($formData, $otherFullName . '_raw', FArrayHelper::getValue($formData, $otherFullName, ''));

if (is_array($v))
{
$v = FArrayHelper::getValue($v, 0, '');
}

$query->where($db->qn($otherField) . ' = ' . $db->quote($v));
}

if (!empty($otherField2))
{
// $$$ the array thing needs fixing, for now just grab 0
$formData = $elementModel->getForm()->formData;
$v = FArrayHelper::getValue($formData, $otherFullName2 . '_raw', FArrayHelper::getValue($formData, $otherFullName2, ''));

if (is_array($v))
{
$v = FArrayHelper::getValue($v, 0, '');
}

$query->where($db->qn($otherField2) . ' = ' . $db->quote($v));
}

/* $$$ hugh - need to check to see if we're editing a record, otherwise
* will fail 'cos it finds the original record (assuming this element hasn't changed)
* @TODO - is there a better way getting the rowid? What if this is form a joined table?
*/

$rowId = $input->get('rowid');

if (!empty($rowId))
{
$query->where($table->db_primary_key . ' != ' . $db->q($rowId));
}

$db->setQuery($query);
$c = $db->loadResult();

return ($c == 0) ? true : false;
}

/**
* Gets the other element model to compare this plugins element data against
*
* @return object element model
*/

private function getOtherElement($suffix = '')
{
$params = $this->getParams();
$otherField = $params->get('areuniquevalues-otherfield' . $suffix);

return FabrikWorker::getPluginManager()->getElementPlugin($otherField);
}

/**
* Gets the hover/alt text that appears over the validation rule icon in the form
*
* @return string label
*/

protected function getLabel()
{
$params = $this->getParams();
$otherField = $params->get('areuniquevalues-otherfield');
$otherField2 = $params->get('areuniquevalues-otherfield2');
$tipText = $params->get('tip_text', '');

if (empty($tipText) && ((int) $otherField !== 0 || (int) $otherField2 !== 0))

{
$labels = array();

if ((int)$otherField !== 0)
{
$otherElementModel = $this->getOtherElement();
$labels[] = $otherElementModel->getElement()->label;
}

if ((int)$otherField2 !== 0)
{
$otherElementModel = $this->getOtherElement('2');
$labels[] = $otherElementModel->getElement()->label;
}

$labels = implode(' ' . strtolower(JText::_('COM_FABRIK_AND')) . ' ', $labels);
return JText::sprintf('PLG_VALIDATIONRULE_AREUNIQUEVALUES_ADDITIONAL_LABEL', $labels);

}
else
{
return parent::getLabel();
}
}
}
 
Unfortunately the code formatter removed your own formatting so I can't see what you have added because of that.

As you have spotted, the code is not right. However I have used Git to identify the differences so I can now review it. What we have is the line which gets the parameter for the caseinsensitivity and a lot of other irrelevant stuff.

It turns out that when I said you needed to change "areuniquevalue-validation_condition" to "areuniquevalues-condition" that was wrong - because this is common functionality triggered by the suffix "-validation_condition". So you need to change this back in the XML.

Once I worked this out the remaining fixes were easy to apply (lines with $cond in them in isuniquevalue.php). I attach a file that will hopefully work (but I have to add .txt to the filename to get it to upload - so you will have to remove this).
 

Attachments

  • areuniquevalues.php.txt
    5.5 KB · Views: 15
We are in need of some funding.
More details.

Thank you.

Members online

No members online now.
Back
Top