/** * Method used to populate the cache table in case the form storage mechanism is DB like * @param boolean $check_mod. Defaults to true. If false, it skips the mod time check * @param mixed $id The id to limit for the caching */ protected function fastPopulate($check_mod = true, $id = null) { $fields = array(); $default_values = array(); $type_fields = array(); foreach ($this->formObj as $field => $fieldObj) { if (!$fieldObj->isInDB()) { continue; } $fields[] = $field; $default_values[] = $fieldObj->getDBValue(); $type_fields[] = $fieldObj->getMDB2Type(); } $insert_fields = $fields; $insert_fields[] = 'id'; $insert_fields[] = 'parent'; $update_fields = array(); foreach ($insert_fields as &$field) { $field = '`' . $field . '`'; $update_fields[] = "{$field}=values({$field})"; } $update_fields[] = '`last_modified`=values(`last_modified`)'; $callback = @create_function('$a,$b', 'return "`" . $b . "`";'); if (!$callback) { I2CE::raiseError("Could not create callback reference"); return false; } if ($check_mod) { $mod_time = $this->getLastCachedTime(); } else { $mod_time = 0; } $sel_fields = $fields; $sel_fields[] = 'created'; $sel_fields[] = 'last_modified'; $select = $this->formMech->getRequiredFieldsQuery($this->form, $sel_fields, $id, true, $callback, $mod_time); I2CE_FormStorage::releaseStorage($this->form); if (!$select) { I2CE::raiseError("Could not get required fields for {$this->form}"); return false; } $fields = array_diff($fields, array('parent', 'id')); $d_fields = array(); foreach ($fields as $field) { $d_fields[] = "IFNULL(`{$field}`, ?) as `{$field}`"; } $select = "SELECT concat('{$this->form}|',id) as id, parent , IFNULL(`last_modified`,'1900-01-01 00:00:00') as `last_modified`, IFNULL(`created`,'0000-00-00 00:00:00') as `created`, " . implode(',', $d_fields) . " FROM ({$select}) AS cached_table"; $insertQry = 'INSERT INTO ' . $this->table_name . '(id,parent,`last_modified`,created,`' . implode('`,`', $fields) . '`) (' . $select . ") ON DUPLICATE KEY UPDATE " . implode(',', $update_fields); $db = MDB2::singleton(); $hash = md5($insertQry); if (array_key_exists($hash, self::$prepared_stash)) { $prp = self::$prepared_stash[$hash]; } else { self::$prepared_stash[$hash] = $prp = $db->prepare($insertQry, $type_fields, MDB2_PREPARE_MANIP); if (I2CE::pearError($prp, "Could not prepare fast populate - trying to reestablish db connection to clear prepared statement cache")) { if (!($db = I2CE::dbReconnect())) { die("COULD NOT RECONNECT TO DB"); } else { I2CE::raiseError("Successful reconnect"); } self::$prepared_stash[$hash] = $prp = $db->prepare($insertQry, $type_fields, MDB2_PREPARE_MANIP); } } if (I2CE::pearError($prp, "Could not prepare fast populate")) { return false; } if (I2CE_CachedForm::$spam) { I2CE::raiseError("Fast Populate Query:{$insertQry}\n"); } $res = $prp->execute($default_values); if (I2CE::pearError($res, "Could not populate cach for {$this->form}:")) { return false; } if ($id || $check_mod) { $prp->free(); unset(self::$prepared_stash[$hash]); } if (I2CE_CachedForm::$spam) { I2CE::raiseError("Updated {$res} records for {$this->form}" . ($id !== null ? " ({$id})" : "")); } return true; }