/** * Retrieve attributes attached to specified row_id in specified table * Returns a list (indexed array) of Attribute objects. * * @param $po_db Db Database connection object * @param $pn_table_num int The table number of the table to fetch attributes for * @param $pa_row_ids array List of row_ids to fetch attributes for * @param $pa_options array Optional array of options. Supported options include: * resetCache = Clear cache before prefetch. [Default is false] * * @return boolean Always return true */ public static function prefetchAttributes($po_db, $pn_table_num, $pa_row_ids, $pa_element_ids, $pa_options = null) { if (!sizeof($pa_row_ids)) { return true; } if (!is_array($pa_element_ids) || !sizeof($pa_element_ids)) { return true; } if (caGetOption('resetCache', $pa_options, false)) { ca_attributes::$s_get_attributes_cache = array(); } // Make sure the element_id list looks like element_ids and does not have blanks $va_element_ids = array(); foreach ($pa_element_ids as $vn_i => $vn_element_id) { if ($vn_element_id) { $va_element_ids[] = $vn_element_id; } } if (!is_array($va_element_ids) || !sizeof($va_element_ids)) { return true; } $qr_attrs = $po_db->query("\n\t\t\tSELECT \n\t\t\t\tcaa.attribute_id, caa.locale_id, caa.element_id element_set_id, caa.row_id,\n\t\t\t\tcaav.value_id, caav.item_id, caav.value_longtext1, caav.value_longtext2,\n\t\t\t\tcaav.value_decimal1, caav.value_decimal2, caav.value_integer1, caav.value_blob,\n\t\t\t\tcme.element_id, cme.datatype, cme.settings, cme.element_code\n\t\t\tFROM ca_attributes caa\n\t\t\tINNER JOIN ca_attribute_values AS caav ON caa.attribute_id = caav.attribute_id\n\t\t\tINNER JOIN ca_metadata_elements AS cme ON cme.element_id = caav.element_id\n\t\t\tWHERE\n\t\t\t\t(caa.table_num = ?) AND (caa.row_id IN (?)) AND (caa.element_id IN (?))\n\t\t\tORDER BY\n\t\t\t\tcaa.attribute_id\n\t\t", array((int) $pn_table_num, $pa_row_ids, $va_element_ids)); if ($po_db->numErrors()) { return false; } $va_attrs = array(); $vn_last_attribute_id = $vn_last_row_id = null; $vn_val_count = 0; $o_attr = $vn_last_element_id = null; while ($qr_attrs->nextRow()) { $va_raw_row = $qr_attrs->getRow(); if ($vn_last_attribute_id != $va_raw_row['attribute_id']) { if ($vn_last_attribute_id && $vn_last_row_id) { $va_attrs[$vn_last_row_id][$vn_last_element_id][] = $o_attr; $vn_val_count = 0; } $vn_last_attribute_id = $va_raw_row['attribute_id']; $vn_last_row_id = $va_raw_row['row_id']; $vn_last_element_id = $va_raw_row['element_set_id']; // when creating the attribute you want element_id = to the "set" id (ie. the element_id in the ca_attributes row) so we overwrite // the element_id of the ca_attribute_values row before we pass the array to Attribute() below $o_attr = new Attribute(array_merge($va_raw_row, array('element_id' => $va_raw_row['element_set_id']))); } $o_attr->addValueFromRow($va_raw_row); $vn_val_count++; } if ($vn_val_count > 0) { $va_attrs[$vn_last_row_id][$vn_last_element_id][] = $o_attr; } $va_row_id_with_no_attributes = array_flip($pa_row_ids); foreach ($va_attrs as $vn_row_id => $va_attrs_by_element) { foreach ($va_attrs_by_element as $vn_element_id => $va_attrs_for_element) { unset($va_row_id_with_no_attributes[$vn_row_id]); ca_attributes::$s_get_attributes_cache[(int) $pn_table_num . '/' . (int) $vn_row_id][(int) $vn_element_id] = $va_attrs_for_element; // Limit cache size if (sizeof(ca_attributes::$s_get_attributes_cache) > ca_attributes::$s_attribute_cache_size) { //array_shift(ca_attributes::$s_get_attributes_cache); if (($vn_splice_length = ceil(sizeof(ca_attributes::$s_get_attributes_cache) - ca_attributes::$s_attribute_cache_size + ca_attributes::$s_attribute_cache_size * 0.5)) > ca_attributes::$s_attribute_cache_size) { $vn_splice_length = ca_attributes::$s_attribute_cache_size; } array_splice(ca_attributes::$s_get_attributes_cache, 0, $vn_splice_length); } } foreach ($pa_element_ids as $vn_id) { if (!isset(ca_attributes::$s_get_attributes_cache[(int) $pn_table_num . '/' . (int) $vn_row_id][$vn_id])) { ca_attributes::$s_get_attributes_cache[(int) $pn_table_num . '/' . (int) $vn_row_id][$vn_id] = false; } } } // Fill in cache entries for row_ids with no attributes as an empty array // to avoid repeated checks for values that don't exist foreach ($va_row_id_with_no_attributes as $vn_row_id => $vn_dummy) { foreach ($va_element_ids as $vn_element_id) { ca_attributes::$s_get_attributes_cache[(int) $pn_table_num . '/' . (int) $vn_row_id][(int) $vn_element_id] = array(); } // Limit cache size if (sizeof(ca_attributes::$s_get_attributes_cache) > ca_attributes::$s_attribute_cache_size) { //array_shift(ca_attributes::$s_get_attributes_cache); if (($vn_splice_length = ceil(sizeof(ca_attributes::$s_get_attributes_cache) - ca_attributes::$s_attribute_cache_size + ca_attributes::$s_attribute_cache_size * 0.5)) > ca_attributes::$s_attribute_cache_size) { $vn_splice_length = ca_attributes::$s_attribute_cache_size; } array_splice(ca_attributes::$s_get_attributes_cache, 0, $vn_splice_length); } } return true; }