Search

Hi all,

This issue relates specifically to Hashid Field extension, I think I've tracked down part of the issue, but I'm not certain.

I've just created an event that allows multiple entries to be created at once, i.e. Allow Multiple.

It is a custom event though, so I don't want to rule out any quirks there, something to keep in mind, however on form submit the event fires, and the entries are created successfully. All is good, except Symphony throws a fatal error:

Symphony Fatal Database Error: Duplicate entry '178' for key 'entry_id'

Tracing the issue it seems to occur in my Hashid Field extension, however I can't actually see the duplicate attempt in the mysql log. You can see the two individual entries (which is expected, as it's Allowing Multiple):

INSERT INTO `sym_entries_data_44` (`value`, `entry_id`) VALUES ('AyJAxg', '177');
INSERT INTO `sym_entries_data_43` (`value`, `entry_id`) VALUES ('kok7Jo', '177');

INSERT INTO `sym_entries_data_44` (`value`, `entry_id`) VALUES ('8yAEWy', '178');
INSERT INTO `sym_entries_data_43` (`value`, `entry_id`) VALUES ('mr9v4o', '178');

This is a two fold issue:

[Edited to remove a misunderstand of mine] I have a feeling that sym_entries_data_44 shouldn't be cropping up here, either. This is the Hashid field from another section, that has an event that fires just before this one. The event that's producing the error uses the value from sym_entries_data_44 to create a link between sections. The thing is, in the example above you'll see they have the same ID, which is wrong. In that particular case the ID of the entry that field relates to is 176 - so that's an issue in itself. Those values are getting recorded in the database and build up over time, never to be deleted, as they don't actually belong to a real entry.

Secondly duplicate entries should be filtered out with the following function anyway, I assume (this is a compile function borrowed from elsewhere):

public function compile(&$entry) {
self::$compiling = $this->get('id');

$driver = Symphony::ExtensionManager()->create('hashid_field');

self::$compiling = 0;
$entry_id = $entry->get('id');
$field_id = $this->get('id');
$data = $entry->getData($field_id);

if($data == null){
    $hash = new HashidsHashids( $this->get('salt') , $this->get('length') );
    $hash = $hash->encrypt($entry_id);
    $result = Symphony::Database()->insert(array('value' => $hash, 'entry_id' => $entry_id), "sym_entries_data_".$field_id );
}

Ignoring the hashing code which is I assume irrelevant, it seems to me what this is supposed to do is attempt to get the entry about to be created, and only allow its creation if it doesn't already exit. This function executes every time though, $data is always null. So how could a duplicate entry ever be created?

Anyone got any ideas?

Edit:

Looking at the mysql query logs with that error, I notice all of the fields look like this:

DELETE FROM sym_entries_data_34 WHERE `entry_id` = 186;
INSERT INTO `sym_entries_data_34` (`entry_id`, `value`, `handle`) VALUES ('186', 'helloworld', 'helloworld');

But the two Hashid field's just INSERT, should I be adding a DELETE before each one? Given this is for a new entry, I assume this is a safety measure to help avoid duplicate entry issues - perhaps like the one I'm facing now :p

Ok so adding a delete before the insert does seem to have removed the error. I'm not 100% sure it's fixed the problem (I worry that this is silenced it, rather than removed it), so I;d still be keen to hear what others think :)

Code I added was this, just before the $result declaration in the above compile snippet:

$delete = Symphony::Database()->delete("sym_entries_data_".$field_id, sprintf(" `entry_id` = %d", $entry_id ));

This is hilarious, but that shouldn't be sym, but tbl, I've tried to write this out several times now and however I format it it still changes it to sym!

Deleted post

I'm definitely getting redundant db entries though, I think this must be the custom events, rather than the field.

I'm seeing values that should only be being stored in one fields table, stored in other places (all in the sections linked via this chain of events), i.e. from my first post:

INSERT INTO `sym_entries_data_44` (`value`, `entry_id`) VALUES ('AyJAxg', '177');
INSERT INTO `sym_entries_data_43` (`value`, `entry_id`) VALUES ('kok7Jo', '177');

Note that these two different fields are in different sections, but somehow fire at the same time. So in this case sym_entries_data_44 ends up with that completely redundant entry that will never be removed. It doesn't relate to anything. This doesn't cause an issue apart from needlessly filling up the database over time with unwanted entries.

I can't see if this is happening in my extension or in my custom events, but the __trigger for the middle event (Event 2 of 3) looks like:

protected function __trigger()
    {
        // Clear id from post, as that will only relate to the contact.
        unset($_POST['id']);

        unset($_POST['fields']);
        $_POST['fields'] = $this->post[self::ROOTELEMENT]['fields'];

        include(TOOLKIT . '/events/event.section.php');

        // Check that this event returned successfully, if it did then fire the flight and link it to the claim
        if($result->getAttribute('result') == "success")
        {
            $_POST['action']['create-contact'] = 'Submit';
            foreach ($_POST['create-contact']['fields'] as $key => $value) {
               $_POST['create-contact']['fields'][$key]['group'] = $result->getAttribute('id');
            }
        }

        return $result;
    }

If anything was causing an issue, I'd expect it to be this - or it could even be the way it interacts with this, from the Hashid Field driver:

public function compileFrontendFields($context) {
        foreach (self::$fields as $field) {
            $field->compile($context['entry']);
        }
    }

It's as if every instance of the Hashid Field is fired when each of the 3 events fired, rather than only when their own event fires, maybe?

Any ideas I'm all ears!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details