32 if ( !defined(
'DATAFACE_EXTENSION_LOADED_APC') ){
34 define(
'DATAFACE_EXTENSION_LOADED_APC',extension_loaded(
'apc'));
39 import(
'Dataface/Error.php');
40 import(
'Dataface/Globals.php');
41 import(
'Dataface/Relationship.php');
42 import(
'Dataface/converters/date.php');
43 import(
'Dataface/Application.php');
45 import(
'SQL/Parser.php');
46 import(
'SQL/Parser/wrapper.php');
47 import(
'Dataface/Serializer.php');
48 import(
'Dataface/ConfigTool.php');
50 define(
'Dataface_Table_UseCache',
false);
56 $GLOBALS[
'Dataface_Table_DefaultFieldPermissions'] = array(
61 $GLOBALS[
'Dataface_Table_DefaultTablePermissions'] = array(
67 define(
'SCHEMA_INVALID_ADDRESS_ERROR', 1);
68 define(
'SCHEMA_NO_SUCH_FIELD_ERROR',2);
69 define(
'SCHEMA_AMBIGUOUS_FIELD_ERROR',3);
70 define(
'Dataface_SCHEMA_NO_VALUE_ASSIGNED', 4);
71 define(
'Dataface_SCHEMA_INDEX_OUT_OF_BOUNDS_ERROR', 5);
72 define(
'Dataface_SCHEMA_SQL_ERROR', 6);
73 define(
'Dataface_SCHEMA_NO_SUCH_RELATIONSHIP_ERROR',7);
74 define(
'Dataface_SCHEMA_INVALID_VALUE_ERROR',8);
75 define(
'DATAFACE_TABLE_SQL_PARSE_ERROR', 9);
76 define(
'DATAFACE_TABLE_RELATED_RECORD_CREATION_ERROR', 10);
77 define(
'DATAFACE_TABLE_RELATED_RECORD_REQUIRED_FIELD_MISSING_ERROR',12);
78 define(
'DATAFACE_TABLE_RECORD_RELATED_RECORD_BLOCKSIZE', 30);
79 define(
'DATAFACE_TABLE_SQL_ERROR',11);
80 define(
'SCHEMA_TABLE_NOT_FOUND', 12);
134 var $_fields = array();
141 var $_grafted_fields = null;
151 var $_transient_fields = null;
159 var $_parentTable = null;
165 var $_cookedValuelists=array();
190 var $_joinTables = null;
208 var $_proxyViews = array();
216 var $_fieldsByTab = null;
223 var $_relatedFields = array();
229 var $_fieldgroups = array();
235 var $_tabs = array();
243 var $_keys = array();
262 var $_relationships = array();
271 var $_relationshipRanges;
304 var $_relationshipsLoaded =
false;
330 var $_filters = array();
338 var $_importFilters = null;
352 var $_relationshipsConfig;
357 var $_valuelistsConfig;
362 var $_actionsLoaded =
false;
367 var $_actionsConfig = null;
380 var $_permissionsLoaded =
false;
385 var $translations = null;
391 var $_cache = array();
397 var $metadataColumns = null;
403 var $_securityFilter = array();
408 var $_securityFilterLoaded =
false;
419 var $descriptionField;
434 var $lastUpdatedField;
439 var $publicLinkTemplate;
451 var $_global_field_properties;
474 public static function &
loadTable($name,
$db=null, $getAll=
false, $quiet=
false){
475 if ( !is_string($name) ){
476 throw new Exception(
"In Dataface_Table::loadTable() expected first argument to be a string but received '".get_class($name).
"'", E_USER_ERROR);
479 if (
$db === null and defined(
'DATAFACE_DB_HANDLE'))
$db = DATAFACE_DB_HANDLE;
480 if ( !isset( $_tables ) ){
481 static $_tables = array();
490 if ( !isset( $_tables[$name] ) ){
495 $_tables[$name]->postInit();
498 return $_tables[$name];
512 throw new Exception(
"Invalid tablename specified: $tablename", E_USER_ERROR);
515 throw new Exception(
"Invalid character found in table '$tablename'.", E_USER_ERROR);
518 import(
'Dataface/Record.php');
525 if (
$db === null and defined(
'DATAFACE_DB_HANDLE') )
$db = DATAFACE_DB_HANDLE;
530 $this->tablename = str_replace(
' ',
'', $this->tablename);
533 $this->_atts = array();
540 $apc_key = DATAFACE_SITE_PATH.
'-Table.php-'.$this->tablename.
'-columns';
541 $apc_key_fields = $apc_key.
'-fields';
542 $apc_key_keys = $apc_key.
'-keys';
543 $apc_key_mtime = $apc_key.
'__mtime';
544 if ( DATAFACE_EXTENSION_LOADED_APC
546 ( !@$_GET[
'--refresh-apc'] )
548 ( @$mod_times[$this->tablename] < apc_fetch($apc_key_mtime) )
550 ( $this->_fields = apc_fetch($apc_key_fields) )
552 ( $this->_keys = apc_fetch($apc_key_keys) )
555 $fieldnames = array_keys($this->_fields);
562 $res = mysql_query(
"SHOW COLUMNS FROM `".$this->tablename.
"`", $this->db);
565 return PEAR::raiseError(
"Error performing mysql query to get column information from table '".$this->tablename.
"'. The mysql error returned was : '".mysql_error($this->
db));
567 throw new Exception(
"Error performing mysql query to get column information from table '".$this->tablename.
"'. The mysql error returned was : '".mysql_error($this->
db), E_USER_ERROR);
572 if ( mysql_num_rows($res) > 0 ){
573 while ( $row = mysql_fetch_assoc($res) ){
590 $widget[
'label'] = ucfirst(str_replace(
'_',
' ',$row[
'Field']));
591 $widget[
'description'] =
'';
592 $widget[
'label_i18n'] = $this->tablename.
'.'.$row[
'Field'].
'.label';
593 $widget[
'description_i18n'] = $this->tablename.
'.'.$row[
'Field'].
'.description';
594 $widget[
'macro'] =
'';
595 $widget[
'helper_css'] =
'';
596 $widget[
'helper_js'] =
'';
597 $widget[
'type'] =
'text';
598 $widget[
'class'] =
'';
599 $widget[
'atts'] = array();
600 if ( preg_match(
'/text/', $row[
'Type']) ){
601 $widget[
'type'] =
'textarea';
602 }
else if ( preg_match(
'/blob/', $row[
'Type']) ){
603 $widget[
'type'] =
'file';
608 $widget[
'class'] =
'default';
611 $row[
'widget'] =& $widget;
612 $row[
'tableta'] =
'default';
613 $row[
'vocabulary'] =
'';
614 $row[
'enforceVocabulary'] =
false;
615 $row[
'validators'] = array();
616 $row[
'name'] = $row[
'Field'];
618 $row[
'repeat'] =
false;
619 $row[
'visibility'] = array(
'list'=>
'visible',
'browse'=>
'visible',
'find'=>
'visible');
631 $this->_fields[ $row[
'Field'] ] = $row;
632 if ( strtolower($row[
'Key']) == strtolower(
'PRI') ){
633 $this->_keys[ $row[
'Field'] ] =& $this->_fields[ $row[
'Field'] ];
640 mysql_free_result($res);
647 $fieldnames = array_keys($this->_fields);
648 foreach ($fieldnames as $key){
651 if ( preg_match(
'/^(.*)_mimetype$/', $key, $matches) and
652 isset( $this->_fields[$matches[1]] )
655 $this->_fields[$key][
'widget'][
'type'] =
'hidden';
656 $this->_fields[$matches[1]][
'mimetype'] = $key;
657 $this->_fields[$key][
'metafield'] =
true;
658 }
else if ( preg_match(
'/^(.*)_filename$/', $key, $matches) and
659 isset( $this->_fields[$matches[1]] ) and
660 $this->
isBlob($matches[1]) ){
661 $this->_fields[$key][
'widget'][
'type'] =
'hidden';
662 $this->_fields[$matches[1]][
'filename'] = $key;
663 $this->_fields[$key][
'metafield'] =
true;
664 }
else if ( preg_match(
'/password/', strtolower($key) ) ){
665 $this->_fields[$key][
'widget'][
'type'] =
'password';
666 }
else if ( $this->_fields[$key][
'Extra'] ==
'auto_increment'){
667 $this->_fields[$key][
'widget'][
'type'] =
'hidden';
668 }
else if ( preg_match(
'/^date/', strtolower($this->_fields[$key][
'Type']) ) ){
669 $this->_fields[$key][
'widget'][
'type'] =
'calendar';
671 if ( !preg_match(
'/time/', strtolower($this->_fields[$key][
'Type']) ) ){
672 $this->_fields[$key][
'widget'][
'showsTime'] =
false;
673 $this->_fields[$key][
'widget'][
'ifFormat'] =
'%Y-%m-%d';
675 }
else if ( preg_match(
'/timestamp/', strtolower($this->_fields[$key][
'Type']) ) ){
676 $this->_fields[$key][
'widget'][
'type'] =
'static';
677 }
else if ( strtolower(substr($this->_fields[$key][
'Type'],0, 4)) ==
'time'){
678 $this->_fields[$key][
'widget'][
'type'] =
'time';
679 }
else if ( substr($this->_fields[$key][
'Type'], 0,4) ==
'enum' ){
680 $this->_fields[$key][
'widget'][
'type'] =
'select';
683 if ( DATAFACE_EXTENSION_LOADED_APC ){
684 apc_store($apc_key_fields, $this->_fields);
685 apc_store($apc_key_keys, $this->_keys);
686 apc_store($apc_key_mtime, time());
690 $this->_loadFieldsIniFile();
693 if ( isset($parent) ){
694 foreach ( array_keys($this->
keys()) as $currkey ){
695 $this->_fields[$currkey][
'widget'][
'type'] =
'hidden';
702 foreach (array_keys($this->_fields) as $field_name ){
703 if ( isset($this->_fields[$field_name][
'order']) ) {
707 else $this->_fields[$field_name][
'order'] = $curr_order++;
720 foreach ($fieldnames as $key){
721 $row =& $this->_fields[$key];
726 if ( preg_match(
'/^(enum|set)\(([^\)]+)\)$/', $row[
'Type'], $matches )){
729 $options = explode(
',', $matches[2]);
732 foreach ( $options as $val){
733 $val = substr($val,1,strlen($val)-2);
737 $valuelists[$row[
'name'].
"_values"] =& $vocab;
738 if ( !@$row[
'vocabulary'] ) $row[
'vocabulary'] = $row[
'name'].
"_values";
741 if ( strtolower($matches[1]) ==
'set'){
742 $row[
'repeat'] =
true;
744 $row[
'repeat'] =
false;
747 $row[
'widget'][
'type'] =
'select';
749 $opt_keys = array_keys($vocab);
753 $widget[
'type'] =
'checkbox';
765 if ( !$this->
isBlob($row[
'name']) and
766 !$this->
isText($row[
'name']) and
767 !$this->
isDate($row[
'name']) and
769 $row[
'Null'] !=
'YES' and
770 strlen($row[
'Default']) == 0 and
771 $row[
'Extra'] !=
'auto_increment' and
772 @$row[
'validators'][
'required'] !== 0){
773 $row[
'validators'][
'required' ] = array(
'message' => $row[
'widget'][
'label'] .
" is a required field.",
775 }
else if ( @$row[
'validators'][
'required'] === 0 ){
776 unset($row[
'validators'][
'required']);
781 if ( $row[
'widget'][
'type'] ==
'checkbox' and isset( $row[
'vocabulary'] ) and ( $this->
isText($key) or $this->
isChar($key) ) ){
782 if ( isset( $row[
'repeat'] ) and !$row[
'repeat'] ){
785 $row[
'repeat'] =
true;
788 if ( !isset($row[
'repeat']) ) $row[
'repeat'] =
false;
789 if ( $row[
'repeat'] and !isset( $row[
'separator'] )){
790 $row[
'separator'] =
"\n";
793 if ( !isset($row[
'display']) and $this->
isText($row[
'name']) ) $row[
'display'] =
'block';
794 else if ( !isset($row[
'display']) ) $row[
'display'] =
'inline';
803 uasort($this->_fields, array(&$this,
'_compareFields'));
819 if ( isset($parent) ){
820 $pdelegate =& $parent->getDelegate();
821 if ( isset($pdelegate) and method_exists($pdelegate,
'init') ){
822 $res = $pdelegate->init($this);
826 if ( $delegate !== null and method_exists($delegate,
'init') ){
827 $res = $delegate->init($this);
830 foreach ( array_keys($this->_fields) as $key){
831 $this->_fields[$key][
'widget'][
'description'] = $this->
getFieldProperty(
'widget:description', $key);
832 $this->_fields[$key][
'widget'][
'label'] = $this->
getFieldProperty(
'widget:label', $key);
833 $this->_fields[$key][
'vocabulary'] = $this->
getFieldProperty(
'vocabulary', $key);
834 $this->_fields[$key][
'widget'][
'type'] = $this->
getFieldProperty(
'widget:type', $key);
835 $this->_fields[$key][
'widget'] = array_merge($this->_fields[$key][
'widget'], $this->
getFieldProperty(
'widget', $key));
838 if ( count($this->_securityFilter) == 0 ){
870 $addr = array_map(
'trim', explode(
'.', $address) );
871 if (
sizeof($addr) != 2 ) {
881 if ( !isset(
$fields[ $addr[1] ] ) ){
918 $index[
$tablename] = mysql_num_rows(mysql_query(
"show tables like '".addslashes($tablename).
"'", $app->db()));
946 if ( $relationship->hasField(
$fieldname,
true,
true) )
return true;
953 if ( $delegate !== null and method_exists($delegate,
'field__'.
$fieldname) )
return true;
955 if ( isset($transient[
$fieldname]) )
return true;
959 if ( isset($parent) and $parent->hasField($fieldname, $checkParent) )
return true;
985 }
else if ( strpos(
$field,
'.') > 0 ){
991 if ( is_array($columnList) ){
992 foreach ( $columnList as $column ){
993 if ( preg_match(
'/^(\w+)\.'.
$field.
'$/', $column) ){
999 foreach ($tablenames as
$table){
1000 if ( self::fieldExists($table.
'.'.
$field,
$db) ){
1001 $name = $table.
'.'.
$field;
1011 throw new Exception($err->toString(), E_USER_WARNING);
1038 function _fieldsIniFilePath(){
1039 return $this->basePath().
'/tables/'.basename($this->tablename).
'/fields.ini';
1069 $candidates = array();
1072 $type = strtolower($this->
getType($field[
'name']));
1073 if ( !isset($types[$type]) ){
1077 $score = $types[$type];
1079 foreach ($patterns as $pattern=>$value){
1080 if ( preg_match($pattern, $field[
'name']) ){
1085 if ( $forcePattern and !$found ){
1088 $candidates[$field[
'name']] = $score;
1089 if ( !isset($max) ) $max = $field[
'name'];
1090 else if ( $candidates[$max] < $score ){
1091 $max = $field[
'name'];
1108 if ( !isset($this->descriptionField) ){
1111 array(
'text'=>10,
'mediumtext'=>10,
'shorttext'=>10,
'longtext'=>2,
1112 'varchar'=>1,
'char'=>1),
1113 array(
'/description|summary|overview/'=>10,
'/desc/'=>2)
1117 return $this->descriptionField;
1130 if ( !isset($this->createdField) ){
1133 array(
'datetime'=>10,
'timestamp'=>10,
'date'=>1),
1134 array(
'/created|inserted|added|posted|creation|insertion/i'=>10,
'/timestamp/i'=>5)
1138 return $this->createdField;
1149 if ( !isset($this->creatorField) ){
1152 array(
'varchar'=>10,
'char'=>10,
'int'=>5),
1153 array(
'/(created.*by)|(owner)|(posted*by)|(author)|(creator)/i'=>10),
1158 return $this->creatorField;
1171 if ( $this->versionField == -1 ){
1172 $this->versionField = null;
1175 if ( @$field[
'version'] ){
1176 $this->versionField = $field[
'name'];
1191 $this->versionField =
$field;
1208 if ( !isset($this->lastUpdatedField) ){
1210 array(
'datetime'=>10,
'timestamp'=>12),
1211 array(
'/updated|modified|change|modification|update/i'=>10,
'/timestamp/i'=>5)
1214 return $this->lastUpdatedField;
1226 if ( !isset($this->bodyField) ){
1228 array(
'text'=>10,
'longtext'=>10,
'mediumtext'=>10),
1229 array(
'/main|body|content|profile|writeup|bio/i'=>10)
1242 function _compareFields($a,$b){
1243 if ( @$a[
'order'] == @$b[
'order'] )
return 0;
1244 return ( @$a[
'order'] < @$b[
'order'] ) ? -1 : 1;
1267 if ( !isset( $this->_indexes) ){
1268 $this->_indexes = array();
1269 $res = mysql_query(
"SHOW index FROM `".$this->tablename.
"`", $this->db);
1271 throw new Exception(
"Failed to get index list due to a mysql error: ".mysql_error($this->
db), E_USER_ERROR);
1274 while ( $row = mysql_fetch_array($res) ){
1275 if ( !isset( $this->_indexes[ $row[
'Key_name'] ] ) )
1276 $this->_indexes[ $row[
'Key_name'] ] = array();
1277 $index =& $this->_indexes[$row[
'Key_name']];
1278 $index[
'name'] = $row[
'Key_name'];
1279 if ( !isset(
$index[
'columns'] ) )
1280 $index[
'columns'] = array();
1281 $index[
'columns'][] = $row[
'Column_name'];
1282 $index[
'unique'] = ( $row[
'Non_unique'] ?
false : true );
1283 $index[
'type'] = $row[
'Index_type'];
1284 $index[
'comment'] = $row[
'Comment'];
1287 mysql_free_result($res);
1291 return $this->_indexes;
1310 foreach ( array_keys($indexes) as $indexName ){
1311 if ( strtolower($indexes[$indexName][
'type']) ===
'fulltext' ){
1312 foreach ( $indexes[$indexName][
'columns'] as $col ){
1331 function getCharFields($includeGraftedFields=
false, $excludeUnsearchable=
false){
1332 if ( !isset($this->_cache[__FUNCTION__]) ){
1334 foreach ( array_keys($this->
fields(
false, $includeGraftedFields)) as
$field){
1335 if ( $this->
isChar($field) or $this->
isText($field) or (strtolower($this->
getType($field)) ==
'enum') or ($this->
getType($field) ==
'container') ){
1336 if ( $excludeUnsearchable and !$this->
isSearchable($field) )
continue;
1340 $this->_cache[__FUNCTION__] =
$out;
1342 return $this->_cache[__FUNCTION__];
1355 return !@$fld[
'not_searchable'];
1370 if ( !isset(
$field[
'metafield']) ){
1372 $field_names = array_keys(
$fields);
1373 foreach ( $field_names as $fn){
1376 $field[
'metafield'] =
true;
1380 if ( !isset(
$field[
'metafield']) ){
1381 $field[
'metafield'] =
false;
1384 return $field[
'metafield'];
1401 if ( !isset($this->metadataColumns) ){
1402 $metatablename = $this->tablename.
'__metadata';
1403 $sql =
"SHOW COLUMNS FROM `{$metatablename}`";
1404 $res = mysql_query($sql, $this->
db);
1405 if ( !$res || mysql_num_rows($res) == 0){
1407 $res = mysql_query($sql, $this->
db);
1409 if ( !$res )
throw new Exception(mysql_error($this->
db), E_USER_ERROR);
1410 if ( mysql_num_rows($res) == 0 )
throw new Exception(
"No metadata table set up for table '{$this->tablename}'", E_USER_ERROR);
1411 $this->metadataColumns = array();
1412 while ($row = mysql_fetch_assoc($res) ){
1413 if ( substr($row[
'Field'],0,2) ==
'__' ){
1414 $this->metadataColumns[] = $row[
'Field'];
1419 return $this->metadataColumns;
1434 if ( !isset($this->_cache[__FUNCTION__][intval($byTab)][intval($includeTransient)]) ){
1437 if ( isset($parent) ){
1439 $fields = array_merge_recursive_unique($parent->fields($byTab,
false,$includeTransient),
$fields);
1440 uasort(
$fields, array(&$this,
'_compareFields'));
1443 $this->_cache[__FUNCTION__][intval($byTab)][intval($includeTransient)] =&
$fields;
1445 return $this->_cache[__FUNCTION__][intval($byTab)][intval($includeTransient)];
1479 function &
fields($byTab=
false, $includeGrafted=
false, $includeTransient=
false){
1482 if ( !isset($this->_cache[__FUNCTION__][intval($includeGrafted)][intval($includeTransient)]) ){
1487 if ( $includeGrafted ){
1489 foreach (array_keys($grafted_fields) as $fname){
1490 $fields[$fname] =& $grafted_fields[$fname];
1494 if ( $includeTransient ){
1496 foreach ( array_keys($transient_fields) as $fname){
1497 if ( !isset(
$fields[$fname]) )
$fields[$fname] =& $transient_fields[$fname];
1504 uasort(
$fields, array(&$this,
'_compareFields'));
1505 $this->_cache[__FUNCTION__][intval($includeGrafted)][intval($includeTransient)] =&
$fields;
1508 $this->_cache[__FUNCTION__][intval($includeGrafted)][intval($includeTransient)] =& $this->_fields;
1512 return $this->_cache[__FUNCTION__][intval($includeGrafted)][intval($includeTransient)];
1516 if ( !isset( $this->_fieldsByTab ) ){
1517 $this->_fieldsByTab = array();
1519 foreach ( $this->
fields(
false,$includeGrafted, $includeTransient) as
$field){
1521 $tab = ( isset( $field[
'tab'] ) ? $field[
'tab'] :
'__default__');
1523 if ( !isset( $this->_fieldsByTab[ $tab] ) ){
1524 $this->_fieldsByTab[ $tab ] = array();
1526 $this->_fieldsByTab[ $tab ][$field[
'name']] =
$field;
1530 return $this->_fieldsByTab;
1561 $tsql = $this->
sql();
1562 if ( $includeParent ) $includeParent = 1;
1563 else $includeParent = 0;
1565 if ( !isset($this->_cache[__FUNCTION__][intval($includeParent)]) ){
1568 $this->_grafted_fields = array();
1571 $this->_grafted_fields = array();
1572 import(
'SQL/Parser.php');
1573 $parser =
new SQL_Parser(null,
'MySQL');
1574 $data = $parser->parse($tsql);
1575 foreach ( $data[
'columns'] as $col ){
1576 if ( $col[
'type'] !=
'glob' ){
1577 $alias = ( @$col[
'alias'] ? $col[
'alias'] : $col[
'value']);
1578 if ( isset($this->_fields[$alias]) )
continue;
1579 $this->_grafted_fields[$alias] = $this->_newSchema(
'varchar(32)', $alias);
1580 $this->_grafted_fields[$alias][
'grafted']=1;
1581 if ( isset($this->_atts[$alias]) and is_array($this->_atts[$alias]) ){
1583 $this->_parseINISection($this->_atts[$alias], $this->_grafted_fields[$alias]);
1590 if ( $includeParent ){
1593 if ( isset($parent) ){
1594 $this->_grafted_fields = array_merge( $parent->fields(
false,
true), $this->_grafted_fields);
1597 $this->_cache[__FUNCTION__][intval($includeParent)] = $this->_grafted_fields;
1601 return $this->_cache[__FUNCTION__][intval($includeParent)];
1615 if ( !isset($this->_cache[__FUNCTION__][intval($includeParent)]) ){
1616 if ( !isset($this->_transient_fields) ){
1617 $this->_transient_fields = array();
1619 if ( !is_array(
$field) )
continue;
1620 if ( @
$field[
'transient'] ){
1622 $this->_parseINISection(
$field, $curr);
1623 if ( @$curr[
'relationship'] ) $curr[
'repeat'] = 1;
1625 $curr = array_merge_recursive_unique($this->_global_field_properties, $curr);
1626 $schema = $this->_newSchema(
'text',
$fieldname);
1628 $curr = array_merge_recursive_unique($schema, $curr);
1629 $this->_transient_fields[
$fieldname] = $curr;
1632 if ( $includeParent){
1634 if ( isset($parent) ){
1635 $this->_transient_fields = array_merge( $parent->transientFields(), $this->_transient_fields);
1639 $this->_cache[__FUNCTION__][intval($includeParent)] =& $this->_transient_fields;
1644 return $this->_cache[__FUNCTION__][intval($includeParent)];
1651 function _hasFieldsIniFile(){
1653 return file_exists( $this->_fieldsIniFilePath() );
1667 if ( !isset($this->_cache[__FUNCTION__][intval($includeParent)]) ){
1673 $delegate_methods = get_class_methods(get_class($del));
1675 $delegate_fields = preg_grep(
'/^field__/', $delegate_methods);
1677 foreach ($delegate_fields as $dfield){
1678 $dfieldname = substr($dfield,7);
1679 $fields[$dfieldname] = $this->_newSchema(
'varchar(32)', $dfieldname);
1680 $fields[$dfieldname][
'visibility'][
'browse'] =
'hidden';
1681 if ( isset($this->_atts[$dfieldname]) and
1682 is_array($this->_atts[$dfieldname]) ){
1683 $this->_parseINISection($this->_atts[$dfieldname],
$fields[$dfieldname]);
1691 if ( $includeParent){
1693 if ( isset($parent) ){
1698 $this->_cache[__FUNCTION__][intval($includeParent)] =
$fields;
1703 return $this->_cache[__FUNCTION__][intval($includeParent)];
1719 if ( isset($del) and method_exists($del,
'__sql__') ){
1720 return $del->__sql__();
1721 }
else if ( isset($this->_sql) ){
1745 if ( defined(
'XATAFACE_DISABLE_PROXY_VIEWS') and XATAFACE_DISABLE_PROXY_VIEWS ){
1748 $sql = $this->
sql();
1754 $sqlKey = md5($sql);
1755 $viewName =
'dataface__view_'.md5($this->tablename.
'_'.$sqlKey);
1756 if ( isset($this->_proxyViews[$viewName]) and $this->_proxyViews[$viewName])
return $viewName;
1757 else if ( isset($this->_proxyViews[$viewName]) and !$this->_proxyViews[$viewName])
return null;
1761 $this->_proxyViews[$viewName] =
false;
1765 if ( @$this->app->_conf[
'multilingual_content'] and $this->getTranslations() ){
1766 $this->_proxyViews[$viewName] =
false;
1774 $res = mysql_query(
"show tables like '".addslashes($viewName).
"'", df_db());
1775 if ( !$res )
throw new Exception(mysql_error(df_db()));
1776 if ( mysql_num_rows($res) < 1 ){
1777 @mysql_free_result($res);
1779 $res = mysql_query(
"create view `".str_replace(
'`',
'', $viewName).
"` as ".$sql, df_db());
1781 error_log(mysql_error(df_db()));
1782 $this->_proxyViews[$viewName] =
false;
1788 @mysql_free_result($res);
1790 $this->_proxyViews[$viewName] =
true;
1811 return $this->_keys;
1822 if ( !isset( $this->_fields[$name] ) )
return false;
1823 if ( isset( $this->_fields[$name][
'Key'] ) && strtolower($this->_fields[$name][
'Key']) == strtolower(
'PRI') ){
1845 foreach ( array_keys($this->
keys()) as $key){
1846 if ( $this->_fields[$key][
'Extra'] ==
'auto_increment')
continue;
1847 $fields[ $key ] =& $this->_fields[$key];
1866 if ( @
$field[
'tablename'] and
$field[
'tablename'] != $this->tablename ){
1872 if ( isset($delegate) and method_exists($delegate,
$fieldname.
'__default') ){
1873 return call_user_func(array(&$delegate,
$fieldname.
'__default'));
1874 }
else if (
$field[
'Default'] ){
1875 return $field[
'Default'];
1888 function &getFieldsConfig(){
1889 return $this->_fieldsConfig;
1912 if ( !isset($permissions) and is_a($this,
'Dataface_Table') ){
1914 }
else if ( !isset($permissions) ){
1918 $schema = array(
"Field"=>
$fieldname,
"Type"=>$type,
"Null"=>
'',
"Key"=>
'',
"Default"=>
'',
"Extra"=>
'');
1919 $schema = array_merge_recursive_unique($this->_global_field_properties, $schema);
1921 $widget[
'label'] = ucfirst($schema[
'Field']);
1922 $widget[
'description'] =
'';
1925 $widget[
'macro'] =
'';
1926 $widget[
'helper_css'] =
'';
1927 $widget[
'helper_js'] =
'';
1928 $widget[
'class'] =
'';
1929 $widget[
'type'] =
'text';
1930 $widget[
'atts'] = array();
1931 if ( preg_match(
'/text/', $schema[
'Type']) ){
1932 $widget[
'type'] =
'textarea';
1933 }
else if ( preg_match(
'/blob/', $schema[
'Type']) ){
1934 $widget[
'type'] =
'file';
1936 $schema[
'widget'] =& $widget;
1937 $schema[
'tab'] =
'__main__';
1940 $schema[
'tableta'] =
'default';
1941 $schema[
'vocabulary'] =
'';
1942 $schema[
'enforceVocabulary'] =
false;
1943 $schema[
'validators'] = array();
1944 $schema[
'name'] = $schema[
'Field'];
1945 $schema[
'permissions'] = $permissions;
1946 $schema[
'repeat'] =
false;
1947 $schema[
'visibility'] = array(
'list'=>
'visible',
'browse'=>
'visible',
'find'=>
'visible');
1948 $schema = array_merge_recursive_unique($schema, $this->_global_field_properties);
1990 if (!isset( $this->_atts[
'title'] ) ){
1992 if ( $delegate !== null and method_exists($delegate,
'titleColumn') ){
1993 $this->_atts[
'title'] = $delegate->titleColumn();
1995 $bestCandidate = null;
1997 $fieldnames = array_keys($this->_fields);
2000 if ( $bestCandidate === null and $this->
isChar($fieldname) ){
2001 $bestCandidate =
'`'.$fieldname.
'`';
2007 if ( $bestCandidate === null ){
2008 $keynames = array_keys($this->
keys());
2009 $bestCandidate =
"CONCAT(".implode(
",", $keynames).
")";
2011 $this->_atts[
'title'] = $bestCandidate;
2014 return $this->_atts[
'title'];
2032 if ( count(
$path)==1){
2036 if ( $delegate !== null and method_exists($delegate,
"field__$fieldname")){
2037 if ( isset($this->_atts[$fieldname]) ){
2038 $schema = array_merge_recursive_unique($this->_newSchema(
'calculated',$fieldname), $this->_atts[$fieldname]);
2040 $schema = $this->_newSchema(
'calculated', $fieldname);
2045 if ( isset($grafted[$fieldname]) )
return $grafted[
$fieldname];
2048 if ( isset($transient[$fieldname]) )
return $transient[
$fieldname];
2051 if ( isset($parent) and (
$field =& $parent->getField($fieldname) ) ){
2064 if ( !isset( $this->_relatedFields[
$path[0]] ) ) $this->_relatedFields[$path[0]] = array();
2065 if ( !isset( $this->_relatedFields[$path[0]][$path[1]] ) ) {
2074 $this->_relatedFields[$path[0]][$path[1]] =& $relationship->getField($path[1]);
2077 return $this->_relatedFields[$path[0]][$path[1]];
2106 if (
$field[
'tablename'] != $this->tablename ){
2112 if ( $this->tablename !==
$table->tablename ){
2122 $delegate_property_name = str_replace(
':',
'_', $propertyName);
2123 if ( method_exists($delegate,
$fieldname.
'__'.$delegate_property_name) ){
2125 if ( !isset( $params[
'record'] ) ) $params[
'record'] = null;
2126 $methodname =
$fieldname.
'__'.$delegate_property_name;
2127 $res =& $delegate->$methodname($params[
'record'], $params);
2137 $path = explode(
':', $propertyName);
2139 while ( count(
$path)> 0 ){
2140 $temp =& $arr[array_shift(
$path)];
2158 foreach (array_keys($this->
keys()) as
$field){
2159 if (strtolower($this->_fields[$field][
'Extra']) ==
'auto_increment'){
2166 private static $globalFieldsConfig = null;
2168 if ( !isset(self::$globalFieldsConfig) ){
2170 import(
'Dataface/ConfigTool.php');
2172 self::$globalFieldsConfig =& $configTool->loadConfig(
'fields', null);
2176 return self::$globalFieldsConfig;
2185 function _loadFieldsIniFile(){
2188 import(
'Dataface/ConfigTool.php');
2190 $conf =& $configTool->loadConfig(
'fields', $this->tablename);
2192 $conf = array_merge($gConf, $conf);
2194 $appDel =& $app->getDelegate();
2195 if ( method_exists($appDel,
'decorateFieldsINI') ){
2196 $appDel->decorateFieldsINI($conf, $this);
2199 $this->_global_field_properties = array();
2200 if ( isset($conf[
'__global__']) ) $this->_parseINISection($conf[
'__global__'], $this->_global_field_properties);
2201 else $this->_global_field_properties = array();
2203 foreach ($this->_fields as $key=>$val){
2204 if ( isset($conf[$key]) ){
2205 $conf[$key] = array_merge_recursive_unique($this->_global_field_properties, $conf[$key]);
2207 $conf[$key] = $this->_global_field_properties;
2211 foreach ($conf as $key=>$value ){
2212 if ( $key ==
'__sql__' and !is_array($value) ){
2213 $this->_sql = $value;
2217 if ( is_array($value) and @$value[
'decorator'] ){
2218 $event =
new StdClass;
2220 $event->conf =& $value;
2221 $event->table = $this;
2223 $app->fireEvent($value[
'decorator'].
'__decorateConf', $event);
2227 if ( is_array($value) ){
2230 if ( isset($value[
'extends']) and isset($conf[$value[
'extends']]) ){
2231 $conf[$key] = array_merge($conf[$value[
'extends']], $value);
2232 $value = $conf[$key];
2235 if ( isset($value[
'Type']) ){
2237 $ftype = strtolower(preg_replace(
'/\(.*$/',
'',$value[
'Type']));
2239 if ( isset($conf[
'/'.$ftype]) ){
2240 $conf[$key] = $value = array_merge($conf[
'/'.$ftype], $value);
2251 if ( preg_match(
'/fieldgroup:(.+)/', $key, $matches) ){
2253 $this->_fieldgroups[trim($matches[1])] = $value;
2254 $this->_fieldgroups[trim($matches[1])][
'name'] = $matches[1];
2256 $grp =& $this->_fieldgroups[trim($matches[1])];
2257 foreach ($grp as $grpkey=>$grpval){
2258 $tmp = explode(
':',$grpkey);
2259 switch (count($tmp)){
2260 case 2: $grp[$tmp[0]][$tmp[1]] =& $grp[$grpkey];
break;
2261 case 3: $grp[$tmp[0]][$tmp[1]][$tmp[2]] =& $grp[$grpkey];
break;
2262 case 4: $grp[$tmp[0]][$tmp[1]][$tmp[2]][$tmp[3]] =& $grp[$grpkey];
break;
2263 case 5: $grp[$tmp[0]][$tmp[1]][$tmp[2]][$tmp[3]][$tmp[4]] =& $grp[$grpkey];
break;
2268 if ( !isset( $grp[
'label'] ) ) $grp[
'label'] = ucfirst($grp[
'name']);
2269 if ( !isset( $grp[
'description']) ) $grp[
'description'] =
'';
2270 if ( !isset( $grp[
'display']) ) $grp[
'display'] =
"inline";
2271 if ( !isset( $grp[
'element_label_visible'])) {
2272 $grp[
'element_label_visible'] =
true;
2274 if ( !isset($grp[
'element_description_visible'])){
2275 $grp[
'element_description_visible'] =
2276 ($grp[
'display'] ==
'inline' ?
false :
true);
2281 $grp[
'label'] = df_translate(
'tables.'.$this->tablename.
'.fieldgroups.'.$grp[
'name'].
'.label', $grp[
'label']);
2282 $grp[
'description'] = df_translate(
'tables.'.$this->tablename.
'.fieldgroups.'.$grp[
'name'].
'.description', $grp[
'description']);
2283 if ( !isset($grp[
'order']) ) $grp[
'order'] = 0;
2287 else if ( preg_match(
'/tab:(.+)/', $key, $matches) ){
2289 $tabname = trim($matches[1]);
2290 $this->_parseINISection($value, $this->_tabs[$tabname]);
2291 $tabarr =& $this->_tabs[$tabname];
2292 $tabarr[
'name'] = $tabname;
2294 if ( !isset($tabarr[
'label']) ) $tabarr[
'label'] = ucfirst($tabname);
2295 if ( !isset($tabarr[
'description']) ) $tabarr[
'description'] =
'';
2302 else if ( $key ==
"__filters__"){
2304 $this->_filters=$value;
2308 else if ($key ==
"__title__"){
2309 $this->_atts[
'title'] = $value;
2312 else if ( $key ==
'__join__' ){
2313 $this->_joinTables = $value;
2317 else if ( strpos($key,
':') > 0 ){
2320 list($parent, $child) = explode(
':', $key);
2321 if ( !isset( $this->_fields[$parent] ) ){
2322 throw new Exception(
"Error while loading definition for subfield '$key' from the fields.ini file for the table '".$this->tablename.
"'. The field '$parent' does not exist.", E_USER_ERROR);
2325 $field =& $this->_fields[$parent];
2326 if ( !isset(
$field[
'fields']) )
$field[
'fields'] = array();
2327 $curr = $this->_newSchema(
'varchar(255)', $child);
2329 $this->_parseINISection($value, $curr);
2330 $field[
'fields'][$child] =& $curr;
2337 else if ( isset( $this->_fields[ $key ] ) ){
2339 $field =& $this->_fields[$key];
2340 $widget =&
$field[
'widget'];
2341 $permissions =&
$field[
'permissions'];
2342 $validators =&
$field[
'validators'];
2344 if ( isset($value[
'Type']) ) $ftype = $value[
'Type'];
2345 $ftype = strtolower(preg_replace(
'/\(.*$/',
'',$ftype));
2347 if ( isset($conf[
'/'.$ftype]) ){
2348 $conf[$key] = $value = array_merge($conf[
'/'.$ftype], $value);
2354 foreach ( $value as $att => $attval ){
2357 $attpath = explode(
":", $att );
2359 if ( count( $attpath ) == 1 ){
2361 if ( is_array($attval) ){
2362 $field[ $att ] = $attval;
2364 $field[ $att ] = trim( $attval );
2365 if ( strcasecmp($att,
'key') === 0 and strcasecmp($attval,
'pri')===0 and !isset($this->_keys[
$field[
'name']])){
2367 $this->_keys[$field[
'name']] =&
$field;
2376 switch ( $attpath[0] ){
2378 if ( count($attpath) > 2 ){
2379 $widget[ $attpath[1] ][ $attpath[2] ] = trim($attval);
2381 $widget[ $attpath[1] ] = trim($attval);
2386 $permissions[ $attpath[1] ] = trim($attval);
2389 if ( !$attval || $attval ==
'false' ) {
2390 $validators[ $attpath[1] ] = 0;
2394 if ( !isset( $validators[ $attpath[1] ] ) ){
2395 $validators[ $attpath[1] ] = array();
2397 if ( count( $attpath ) <= 2 ){
2398 $validators[ $attpath[1] ][
'arg'] = trim($attval);
2400 $validators[ $attpath[1] ][ $attpath[2] ] = trim($attval);
2402 if ( !isset( $validators[ $attpath[1] ][
'message'] )){
2403 $validators[ $attpath[1] ][
'message'] =
"Illegal input for field ".$field[
'name'];
2408 if ( !isset(
$field[
'visibility'] ) )
$field[
'visibility'] = array(
'list'=>
'visible',
2409 'browse'=>
'visible',
2411 $field[
'visibility'][ $attpath[1] ] = trim($attval);
2416 $field[$attpath[0]][$attpath[1]] = trim($attval);
2430 unset($permissions);
2433 $this->_atts[$key] = $value;
2441 foreach (array_keys($this->_fields) as $key){
2442 if ( isset($this->_fields[$key][
'group']) ){
2443 $grpname = $this->_fields[$key][
'group'];
2444 if ( !isset( $this->_fieldgroups[$grpname] ) ){
2445 $this->_fieldgroups[$grpname] = array(
2447 "label"=>df_translate(
'tables.'.$this->tablename.
'.fieldgroups.'.$grpname.
'.label', ucfirst($grpname)),
2449 "display"=>
'inline',
2450 "element_label_visible"=>
true,
2451 "element_description_visible"=>
false,
2456 if ( strcasecmp($this->_fields[$key][
'Type'],
'container') === 0){
2462 if ( $this->_fields[$key][
'widget'][
'type'] ==
'text' ) $this->_fields[$key][
'widget'][
'type'] =
'file';
2463 if ( !isset( $this->_fields[$key][
'savepath'] ) ){
2464 $this->_fields[$key][
'savepath'] = $this->basePath().
'/tables/'.$this->tablename.
'/'.$key;
2465 }
else if ( strpos($this->_fields[$key][
'savepath'],
'/') !== 0 and !preg_match(
'/^[a-z0-9]{1,5}:\/\//', $this->_fields[$key][
'savepath']) ) {
2466 $this->_fields[$key][
'savepath'] = DATAFACE_SITE_PATH.
'/'.$this->_fields[$key][
'savepath'];
2469 if ( !isset($this->_fields[$key][
'url']) ){
2470 $this->_fields[$key][
'url'] = str_replace(DATAFACE_SITE_PATH, DATAFACE_SITE_URL, $this->_fields[$key][
'savepath']);
2472 }
else if ( strpos( $this->_fields[$key][
'url'],
'/') !== 0 and strpos($this->_fields[$key][
'url'],
'http://') !== 0 ){
2473 $this->_fields[$key][
'url'] = DATAFACE_SITE_URL.
'/'.$this->_fields[$key][
'url'];
2478 if ( !isset($this->_fields[$key][
'tab']) ) $this->_fields[$key][
'tab'] =
'__main__';
2479 $tab = $this->_fields[$key][
'tab'];
2480 if ( !isset($this->_tabs[$tab]) ){
2482 $this->_tabs[$tab] = array(
'name'=>$tab,
'label'=>ucfirst(str_replace(
'_',
' ',$tab)),
'description'=>
'');
2487 if ( $this->_fields[$key][
'widget'][
'type'] ==
'checkbox' and ($this->
isText($key) || $this->
isChar($key)) and @$this->_fields[$key][
'vocabulary'] ){
2489 $this->_fields[$key][
'repeat'] =
true;
2492 $widget =& $this->_fields[$key][
'widget'];
2493 switch ($widget[
'type']){
2495 if ( !isset($widget[
'atts'][
'size']) ){
2497 $widget[
'atts'][
'size'] = 10;
2499 $widget[
'atts'][
'size'] = 30;
2504 if (!isset($widget[
'atts'][
'rows']) ){
2505 $widget[
'atts'][
'rows'] = 6;
2507 if ( !isset($widget[
'atts'][
'cols']) ){
2508 $widget[
'atts'][
'cols'] = 60;
2514 $widget[
'label'] = df_translate(
'tables.'.$this->tablename.
'.fields.'.$key.
'.widget.label',$widget[
'label']);
2515 $widget[
'description'] = df_translate(
'tables.'.$this->tablename.
'.fields.'.$key.
'.widget.description',$widget[
'description']);
2516 if ( isset($widget[
'question']) ){
2517 $widget[
'question'] = df_translate(
'tables.'.$this->tablename.
'.fields.'.$key.
'.widget.question',$widget[
'question']);
2552 function readOnly(){
2586 if ( !isset($filter)){
2589 $query =& $app->getQuery();
2590 if ( class_exists(
'Dataface_AuthenticationTool') ){
2592 $user =& $auth->getLoggedInUser();
2598 foreach ($this->_filters as $key=>$value){
2599 if ( isset($this->_securityFilter[$key]) )
continue;
2600 if ( $value{0} ==
'$' ){
2601 if ( !$user and strpos($value,
'$user') !==
false )
continue;
2602 eval(
'$filter[$key] = "=".'.$value.
';');
2603 }
else if ( substr($value,0,4) ==
'php:' ){
2604 if ( !$user and strpos($value,
'$user') !==
false )
continue;
2605 eval(
'$filter[$key] = "=".'.substr($value,4).
';');
2607 $filter[$key] =
"=".$value;
2613 $this->_securityFilter = $filter;
2624 return array_merge($this->_securityFilter, $filter);
2660 $params[
'relationship'] = $relationshipName;
2692 if ( isset($params[
'record']) ) $record =& $params[
'record'];
2693 else $record = null;
2694 $cachedPermissions = $pt->getCachedPermissions($record, $params);
2695 if ( isset($cachedPermissions) )
return $cachedPermissions;
2700 $appDelegate =& $app->getDelegate();
2702 $recordmask = @$params[
'recordmask'];
2704 if ( isset($params[
'relationship']) ){
2705 if ( isset($params[
'relationshipmask']) ) $rmask =& $params[
'relationshipmask'];
2706 else $rmask = array();
2708 if ( isset($params[
'field']) ){
2709 $relprefix =
'rel_'.$params[
'relationship'].
'__';
2710 $methods[] = array(
'object'=>&$delegate,
'name'=>$relprefix.$params[
'field'].
'__permissions',
'type'=>
'permissions',
'partial'=>1);
2711 $methods[] = array(
'object'=>&$delegate,
'name'=>$relprefix.$params[
'field'].
'__roles',
'type'=>
'roles',
'partial'=>1);
2712 $methods[] = array(
'object'=>&$delegate,
'name'=>$relprefix.
'__field__permissions',
'type'=>
'permissions',
'partial'=>1);
2713 $methods[] = array(
'object'=>&$delegate,
'name'=>$relprefix.
'__field__roles',
'type'=>
'roles',
'partial'=>1);
2716 if ( @$params[
'nobubble'] ) $methods[] =
'break';
2721 $methods[] = array(
'object'=>&$delegate,
'name'=>
'rel_'.$params[
'relationship'].
'__permissions',
'type'=>
'permissions',
'mask'=>&$rmask,
'partial'=>1);
2722 $methods[] = array(
'object'=>&$delegate,
'name'=>
'rel_'.$params[
'relationship'].
'__roles',
'type'=>
'roles',
'mask'=>&$rmask,
'partial'=>1);
2723 if ( isset($parent) ) $methods[] = array(
'object'=>&$parent,
'name'=>
'getPermissions',
'type'=>
'Dataface_Table',
'partial'=>1);
2724 if ( @$params[
'nobubble'] ) $methods[] =
'break';
2726 else if ( isset($params[
'field']) ){
2727 if ( isset($record) and is_a($record,
'Dataface_Record') ){
2728 $methods[] = array(
'object'=>$pt,
'name'=>
'getPortalFieldPermissions',
'type'=>
'permissions',
'partial'=>1);
2730 $methods[] = array(
'object'=>&$delegate,
'name'=>$params[
'field'].
'__permissions',
'type'=>
'permissions',
'partial'=>1);
2731 $methods[] = array(
'object'=>&$delegate,
'name'=>$params[
'field'].
'__roles',
'type'=>
'roles',
'partial'=>1);
2732 $methods[] = array(
'object'=>&$delegate,
'name'=>
'__field__permissions',
'type'=>
'permissions',
'partial'=>1);
2733 $methods[] = array(
'object'=>&$delegate,
'name'=>
'__field__roles',
'type'=>
'roles',
'partial'=>1);
2734 if ( isset($parent) ) $methods[] = array(
'object'=>&$parent,
'name'=>
'getPermissions',
'type'=>
'Dataface_Table',
'partial'=>1);
2735 if ( @$params[
'recordmask'] ) $methods[] =
'recordmask';
2736 if ( @$params[
'nobubble'] ) $methods[] =
'break';
2742 if ( isset($record) and is_a($record,
'Dataface_Record') ){
2743 $methods[] = array(
'object'=>$pt,
'name'=>
'getPortalRecordPermissions',
'type'=>
'permissions',
'partial'=>1);
2745 $methods[] = array(
'object'=>&$delegate,
'name'=>
'getPermissions',
'type'=>
'permissions');
2746 $methods[] = array(
'object'=>&$delegate,
'name'=>
'getRoles',
'type'=>
'roles');
2747 $methods[] = array(
'object'=>&$appDelegate,
'name'=>
'getPermissions',
'type'=>
'permissions');
2748 $methods[] = array(
'object'=>&$appDelegate,
'name'=>
'getRoles',
'type'=>
'roles');
2749 if ( isset($parent) ) $methods[] = array(
'object'=>&$parent,
'name'=>
'getPermissions',
'type'=>
'Dataface_Table');
2752 foreach ($methods as $method){
2753 if ( $method ==
'break' ) {
2754 if ( !$perms )
return null;
2757 if ( $method ==
'recordmask' and is_array($recordmask) ){
2761 $perms = array_merge($recordmask, $perms);
2764 if ( isset($method[
'object']) and method_exists($method[
'object'], $method[
'name']) ){
2765 $name = $method[
'name'];
2766 if ( $method[
'type'] ==
'Dataface_Table'){
2767 $res = $method[
'object']->$name(array_merge($params, array(
'nobubble'=>1)));
2769 $res = $method[
'object']->$name($record, $params);
2771 if ( $method[
'type'] ==
'roles' ){
2774 if ( is_array($res) ){
2775 if ( @$method[
'mask'] and is_array(@$method[
'mask']) ) $res = array_merge($method[
'mask'], $res);
2777 $perms = array_merge($res, $perms);
2778 if ( !@$method[
'partial'] and !@$res[
'__partial__']){
2779 $pt->filterPermissions($record, $perms, $params);
2780 $pt->cachePermissions($record, $params, $perms);
2787 $pt->filterPermissions($record, $res, $params);
2788 $pt->cachePermissions($record,$params,$res);
2803 if ( is_array($roles) ){
2805 foreach ($roles as $role){
2806 if ( is_string($role) ){
2811 }
else if ( is_string($roles) ){
2825 $this->_permissionsLoaded =
true;
2827 $conf =& $configTool->loadConfig(
'permissions', $this->tablename);
2829 $permissionsTool->addPermissions($conf);
2854 if ( $this->translations === null ){
2855 $this->translations = array();
2856 $res = mysql_query(
"SHOW TABLES LIKE '".addslashes($this->tablename).
"%'", $this->
db);
2859 throw new Exception(
2861 'MySQL query error loading translation tables',
2862 'MySQL query error while trying to find translation tables for table "'.addslashes($this->tablename).
'". '.mysql_error($this->
db).
'. ',
2863 array(
'sql_error'=>mysql_error($this->
db),
'stack_trace'=>
'',
'table'=>$this->tablename)
2869 if (mysql_num_rows($res) <= 0 ){
2872 throw new Exception(
2874 'Not enough results returned loading translation tables',
2875 'No tables were returned when trying to load translation tables for table "'.$this->tablename.
'". This query should have at least returned one record (the current table) so there must be a problem with the query.',
2876 array(
'table'=>$this->tablename)
2882 while ( $row = mysql_fetch_array($res ) ){
2889 if ( preg_match(
'/^'.$this->tablename.
'_([a-zA-Z]{2})$/',
$tablename, $matches) ){
2890 $this->translations[$matches[1]] = 0;
2894 mysql_free_result($res);
2898 return $this->translations;
2910 if ( isset( $translations[$name] )){
2912 if ( !$translations[$name] ){
2914 $res = mysql_query(
"SHOW COLUMNS FROM `".addslashes($this->tablename).
"_".addslashes($name).
"`", $this->
db);
2916 throw new Exception(
2918 'Problem loading columns from translation table',
2919 'Problem loading columns from translation table for table "'.$this->tablename.
'" in language "'.$name.
'". ',
2920 array(
'table'=>$this->tablename,
'langauge'=>$name,
'stack_trace'=>
'',
'sql_error'=>mysql_error($this->
db))
2925 $translations[$name] = array();
2926 while ( $row = mysql_fetch_assoc($res) ){
2927 $translations[$name][] = $row[
'Field'];
2929 mysql_free_result($res);
2932 return $translations[$name];
2945 'o-a-c'=>
'Original translation',
2946 'm-u-c'=>
'Machine translation - unapproved',
2947 'm-a-c'=>
'Machine translation - approved',
2948 'm-u-o'=>
'Machine translation - unapproved - out of date',
2949 'm-a-o'=>
'Machine translation - approved - out of date',
2950 'h-u-c'=>
'Human translation - unapproved',
2951 'h-a-c'=>
'Human translation - approved',
2952 'h-u-o'=>
'Human translation - unapproved - out of date',
2953 'h-a-o'=>
'Human translation - approved - out of date'
2976 return (@$this->_atts[
'label'] ? $this->_atts[
'label'] : $this->tablename);
2992 if ( !isset($this->_atts[
'singular_label']) ){
2993 $this->_atts[
'singular_label'] = df_singularize($this->
getLabel());
2995 return $this->_atts[
'singular_label'];
3023 foreach ( array_keys($tables) as
$tablename ){
3034 if ( !isset($this->_cache[__FUNCTION__]) ){
3035 $atts =& $this->_atts;
3037 if ( isset($parent) ){
3038 $atts = array_merge($parent->attributes(), $atts);
3040 $this->_cache[__FUNCTION__] =& $atts;
3042 return $this->_cache[__FUNCTION__];
3055 if ( !isset($this->_parentTable) ){
3056 if ( isset($this->_atts[
'__isa__']) ){
3060 return $this->_parentTable;
3076 return (isset($this->_atts[
'__implements__']) and isset($this->_atts[
'__implements__'][$ontologyName]));
3088 if ( !isset( $this->status ) ){
3093 $res = mysql_query(
"SHOW TABLE STATUS LIKE '".addslashes($this->tablename).
"'",$this->
db);
3096 $res = mysql_query(
"select CREATE_TIME as Create_time, UPDATE_TIME as Update_time from information_schema.tables where TABLE_SCHEMA='".addslashes($dbname).
"' and TABLE_NAME='".addslashes($this->tablename).
"' limit 1", df_db());
3100 throw new Exception(
"Error performing mysql query to obtain status for table '".$this->tablename.
"': ".mysql_error($this->
db), E_USER_ERROR);
3103 $this->status = mysql_fetch_array($res);
3104 mysql_free_result($res);
3107 return $this->status;
3136 static $backup_times = 0;
3137 if ( $backup_times === 0 or $refresh ){
3138 $res = mysql_query(
"select * from dataface__mtimes", df_db());
3140 import(
'Dataface/IO.php');
3142 $res = mysql_query(
"select * from dataface__mtimes", df_db());
3143 if ( !$res )
throw new Exception(mysql_error(df_db()));
3146 $backup_times = array();
3147 while ( $row = mysql_fetch_assoc($res) ){
3148 $backup_times[$row[
'name']] = $row[
'mtime'];
3150 @mysql_free_result($res);
3152 return $backup_times;
3173 static $mod_times = 0;
3174 if ( $mod_times === 0 or $refresh ){
3175 $mod_times = array();
3178 $dbname = $app->_conf[
'_database'][
'name'];
3184 $res = mysql_query(
"show tables", df_db());
3186 throw new Exception(mysql_error(df_db()));
3188 $backup_times = null;
3190 while ($row = mysql_fetch_row($res) ){
3191 $row[
'Name'] = $row[0];
3192 if ( @$row[
'Update_time'] ){
3193 $mod_times[$row[
'Name']] = @strtotime($row[
'Update_time']);
3195 if ( !$backup_times ){
3198 if ( isset($backup_times[$row[
'Name']]) and $backup_times[$row[
'Name']] ){
3199 $mod_times[$row[
'Name']] = $backup_times[$row[
'Name']];
3201 $mod_times[$row[
'Name']] = time();
3202 import(
'Dataface/IO.php');
3219 return $status[
'Update_time'];
3230 return $status[
'Create_time'];
3257 if ( !$options )
return false;
3259 if (count($options) != 2)
return false;
3260 $opt_keys = array_keys($options);
3263 foreach ($opt_keys as $opt_key){
3264 if ( stristr($opt_key,
'n') == $opt_key ) $no_val = $opt_key;
3265 else if ( stristr($opt_key,
'y') == $opt_key) $yes_val = $opt_key;
3266 else if ( $opt_key ==
"0" ) $no_val = $opt_key;
3267 else if ( $opt_key ==
"1" ) $yes_val = $opt_key;
3268 else if ( in_array(strtolower($opt_key), array(
'on',
'active',
'true',
't') ) ){
3269 $yes_val = $opt_key;
3270 }
else if ( in_array(strtolower($opt_key), array(
'off',
'inactive',
'false',
'f') ) ){
3275 if ( $yes_val and $no_val ){
3289 function _valuelistsIniFilePath(){
3290 return $this->basePath().
'/tables/'.$this->tablename.
'/valuelists.ini';
3297 function _hasValuelistsIniFile(){
3298 return file_exists( $this->_valuelistsIniFilePath() );
3318 private function &_loadValuelistsIniFile(){
3319 if ( !isset($this->_valuelistsConfig) ){
3320 import(
'Dataface/ConfigTool.php');
3322 $this->_valuelistsConfig =& $configTool->loadConfig(
'valuelists', $this->tablename);
3324 return $this->_valuelistsConfig;
3341 private function _loadValuelist($name){
3342 if ( !isset($this->_valuelists) ){
3343 $this->_valuelists = array();
3346 if ( !isset($this->_valuelists[$name]) ){
3347 $conf =& $this->_loadValuelistsIniFile();
3348 if ( isset($conf[$name]) ){
3349 $vllist = $conf[$name];
3351 $valuelists =& $this->_valuelists;
3352 foreach ( $vllist as $key=>$value ){
3353 if ( $key ==
'__import__' ){
3356 list( $ext_table, $ext_valuelist ) = explode(
'.', $value);
3357 if ( isset( $ext_table ) && isset( $ext_valuelist ) ){
3359 }
else if ( isset( $ext_table ) ){
3360 $ext_valuelist = $ext_table;
3361 $ext_table =& $this;
3364 if ( isset( $ext_table ) ){
3365 $ext_valuelist = $ext_table->getValuelist( $ext_valuelist );
3366 foreach ( $ext_valuelist as $ext_key=>$ext_value ){
3367 $valuelists[$vlname][$ext_key] = $ext_value;
3374 unset($ext_valuelist);
3375 }
else if ( $key ==
'__sql__' ) {
3380 $res = df_query($value, null,
true,
true);
3381 if ( is_array($res) ){
3383 foreach ($res as $row){
3384 $valuekey = $row[0];
3385 $valuevalue = count($row)>1 ? $row[1] : $row[0];
3386 $valuelists[$vlname][$valuekey] = $valuevalue;
3388 if ( count($row)>2 ){
3389 $valuelists[$vlname.
'__meta'][$valuekey] = $row[2];
3394 throw new Exception(
"Valuelist query '".$value.
"' failed. :".mysql_error(df_db()), E_USER_NOTICE);
3398 $valuelists[$vlname][$key] = $value;
3407 if ( !isset( $this->_valuelists ) ){
3408 $this->_valuelists = array();
3410 $valuelists =& $this->_valuelists;
3412 import(
'Dataface/ConfigTool.php');
3414 $conf =& $configTool->loadConfig(
'valuelists', $this->tablename);
3417 foreach ( $conf as $vlname=>$vllist ){
3418 $valuelists[$vlname] = array();
3419 if ( is_array( $vllist ) ){
3420 foreach ( $vllist as $key=>$value ){
3421 if ( $key ==
'__import__' ){
3424 list( $ext_table, $ext_valuelist ) = explode(
'.', $value);
3425 if ( isset( $ext_table ) && isset( $ext_valuelist ) ){
3427 }
else if ( isset( $ext_table ) ){
3428 $ext_valuelist = $ext_table;
3429 $ext_table =& $this;
3432 if ( isset( $ext_table ) ){
3433 $ext_valuelist = $ext_table->getValuelist( $ext_valuelist );
3434 foreach ( $ext_valuelist as $ext_key=>$ext_value ){
3435 $valuelists[$vlname][$ext_key] = $ext_value;
3442 unset($ext_valuelist);
3443 }
else if ( $key ==
'__sql__' ) {
3448 $res = df_query($value, null,
true,
true);
3449 if ( is_array($res) ){
3451 foreach ($res as $row){
3452 $valuekey = $row[0];
3453 $valuevalue = count($row)>1 ? $row[1] : $row[0];
3454 $valuelists[$vlname][$valuekey] = $valuevalue;
3456 if ( count($row)>2 ){
3457 $valuelists[$vlname.
'__meta'][$valuekey] = $row[2];
3462 throw new Exception(
"Valuelist query '".$value.
"' failed. ", E_USER_NOTICE);
3466 $valuelists[$vlname][$key] = $value;
3482 function &getValuelistsConfig(){
3483 return $this->_valuelistsConfig;
3491 $this->_valuelists = null;
3504 if ( !isset($this->_cookedValuelists[$name]) ){
3505 $this->_cookedValuelists[$name] = null;
3507 if ( method_exists($delegate,
'valuelist__'.$name) ){
3508 $res = call_user_func(array(&$delegate,
'valuelist__'.$name));
3509 if ( is_array($res) ) $this->_cookedValuelists[$name] = $res;
3513 if ( !isset($this->_cookedValuelists[$name]) and isset($parent) ){
3514 $res = $parent->getValuelist($name);
3515 if ( is_array($res) ) $this->_cookedValuelists[$name] = $res;
3519 $appdel =& $app->getDelegate();
3520 if ( !isset($this->_cookedValuelists[$name]) and isset($appdel) and method_exists($appdel,
'valuelist__'.$name) ){
3521 $res = call_user_func(array(&$appdel,
'valuelist__'.$name));
3522 if ( is_array($res) ) $this->_cookedValuelists[$name] = $res;
3525 if ( !isset($this->_cookedValuelists[$name]) and !isset( $this->_valuelists ) ){
3526 $this->_loadValuelistsIniFile();
3528 $this->_loadValuelist($name);
3530 if ( !isset($this->_cookedValuelists[$name]) and isset( $this->_valuelists[$name] ) ){
3531 $this->_cookedValuelists[$name] = $this->_valuelists[$name];
3535 import(
'Dataface/ValuelistTool.php');
3541 if ( isset($this->_cookedValuelists[$name]) and isset($delegate) and method_exists($delegate,
'valuelist__'.$name.
'__decorate') ){
3543 $methodname =
'valuelist__'.$name.
'__decorate';
3544 $this->_cookedValuelists[$name] = $delegate->$methodname($this->_cookedValuelists[$name]);
3545 }
else if ( isset($this->_cookedValuelists[$name]) and isset($appdel) and method_exists($appdel,
'valuelist__'.$name.
'__decorate') ){
3546 $methodname =
'valuelist__'.$name.
'__decorate';
3547 $this->_cookedValuelists[$name] = $appdel->$methodname($this->_cookedValuelists[$name]);
3551 return $this->_cookedValuelists[$name];
3565 if ( !isset( $this->_valuelists ) ){
3567 $this->_loadValuelistsIniFile();
3569 return $this->_valuelists;
3579 $valuelists = array_keys($this->
valuelists());
3581 if ( isset($delegate) ){
3582 $delegate_methods = get_class_methods(get_class($delegate));
3583 $valuelist_methods = preg_grep(
'/^valuelist__/', $delegate_methods);
3584 foreach ( $valuelist_methods as $method ){
3585 $valuelists[] = substr($method, 11);
3588 import(
'Dataface/ValuelistTool.php');
3612 function _relationshipsIniFilePath(){
3613 return $this->basePath().
'/tables/'.$this->tablename.
'/relationships.ini';
3620 function _hasRelationshipsIniFile(){
3622 return file_exists( $this->_relationshipsIniFilePath() );
3633 function _loadRelationshipsIniFile(){
3636 import(
'Dataface/ConfigTool.php');
3638 $conf =& $configTool->loadConfig(
'relationships', $this->tablename);
3640 $r =& $this->_relationships;
3641 foreach ($conf as $rel_name => $rel_values){
3644 if ( is_array( $rel_values ) ){
3652 if ( isset($parent) ){
3653 $this->_relationships = array_merge($parent->relationships(), $this->_relationships);
3655 $this->_relationshipsLoaded =
true;
3668 if ( !is_array($relationship) ){
3669 throw new Exception(
"In Dataface_Table::addRelationship() 2nd argument expected to be an array, but received ", E_USER_ERROR);
3683 if ( array_key_exists(__FUNCTION__,$this->_cache) )
return $this->_cache[__FUNCTION__];
3684 foreach ( array_keys($r) as $name ){
3685 if ( $this->_relationships[$name]->isParentRelationship() ){
3686 $this->_cache[__FUNCTION__] =& $r[$name];
3701 if ( array_key_exists(__FUNCTION__,$this->_cache) )
return $this->_cache[__FUNCTION__];
3702 foreach ( array_keys($r) as $name ){
3703 if ( $r[$name]->isChildrenRelationship() ){
3704 $this->_cache[__FUNCTION__] =& $r[$name];
3724 if ( isset( $this->_relationshipRanges[$relationshipName] ) ){
3725 return $this->_relationshipRanges[$relationshipName];
3727 return $this->_defaultRelationshipRange;
3744 if ( !isset( $this->_relationshipRanges ) ) $this->_relationshipRanges = array();
3745 $this->_relationshipRanges[$relationshipName] = array($lower, $upper);
3757 return $this->_defaultRelationshipRange;
3767 $this->_defaultRelationshipRange = array($lower, $upper);
3775 function &getRelationshipsConfig(){
3776 return $this->_relationshipsConfig;
3791 if ( !is_string($name) )
throw new Exception(
"Relationship name is not a string");
3792 if ( !isset($r[$name]) ){
3793 $err =
PEAR::raiseError(
"Attempt to get relationship nonexistent '$name' from table '".$this->tablename, E_USER_ERROR);
3809 return isset($r[$name]);
3830 $rkeys = array_keys($relationships);
3832 if ( isset( $this->_cache[
'getRelationshipsAsActions']) ){
3833 $actions = $this->_cache[
'getRelationshipsAsActions'];
3836 foreach ( $rkeys as $key){
3837 $srcTable =& $relationships[$key]->getSourceTable();
3838 $actions[$key] = array(
3841 'label'=>ucwords(str_replace(
'_',
' ',$key)),
3842 'url' =>
'{$this->url(\'-action=related_records_list&-relationship='.$key.
'\')}
',
3843 'selected_condition
' => '$query[\
'-relationship\'] == \''.$key.
'\'',
3846 'condition' =>
'$record and $record->checkPermission("view related records", array("relationship"=>"'.basename($key).
'"))',
3848 'visible'=>(!($relationships[$key]->isParentRelationship()) ? 1 : 0)
3850 if ( isset($relationships[$key]->_schema[
'action']) ){
3851 $actions[$key] = array_merge($actions[$key], $relationships[$key]->_schema[
'action']);
3853 $actions[$key][
'label'] = df_translate(
'tables.'.$srcTable->tablename.
'.relationships.'.$key.
'.label', @$actions[$key][
'label']);
3854 $actions[$key][
'description'] = df_translate(
'tables.'.$srcTable->tablename.
'.relationships.'.$key.
'.description', @$actions[$key][
'description']);
3857 $this->_cache[
'getRelationshipsAsActions'] = $actions;
3860 import(
'Dataface/ActionTool.php');
3862 $out = $actionsTool->getActions($params, $actions);
3863 if ( isset($relationshipName) ) {
3864 if ( isset(
$out[$relationshipName]) ){
3865 return @
$out[$relationshipName];
3867 return $actionsTool->getAction($params, $actions[$relationshipName]);
3881 if ( !$this->_relationshipsLoaded ){
3882 $start = microtime_float();
3883 $this->_loadRelationshipsIniFile();
3884 $end = microtime_float()-$start;
3885 if ( DATAFACE_DEBUG ){
3886 $this->app->addDebugInfo(
"Time to load relationships: $end");
3890 return $this->_relationships;
3905 $relationship =& $this->getRelationship(
$path[0]);
3907 $domainTable =& self::loadTable($relationship->getDomainTable());
3908 if ( $domainTable->hasField(
$path[1]) )
return $domainTable;
3911 foreach ($relationship->_schema[
'selected_tables'] as
$table ){
3912 if ( $table == $domainTable->tablename )
continue;
3913 $table =& self::loadTable($table, $this->
db);
3915 if ( $table->hasField(
$path[1]) ){
3949 if ( !isset( $this->_delegate ) ){
3950 if ( $this->_hasDelegateFile() ){
3952 $this->_loadDelegate();
3959 return $this->_delegate;
3976 function _delegateFilePath(){
3977 $path =$this->basePath().
'/tables/'.$this->tablename.
'/'.$this->tablename.
'.php';
3992 function _hasDelegateFile(){
3993 return file_exists( $this->_delegateFilePath() );
4001 function _loadDelegate(){
4003 if ( $this->_hasDelegateFile() ){
4005 import( $this->_delegateFilePath() );
4006 $delegate_name =
"tables_".$this->tablename;
4007 $this->_delegate =
new $delegate_name();
4008 if ( isset($this->_delegate) and method_exists($this->_delegate,
'getDelegate') ){
4009 $del = $this->_delegate->getDelegate();
4011 $this->_delegate = $del;
4015 if ( method_exists($this->_delegate,
'tablePermissions') ){
4019 throw new Exception(
4021 'tablePermissions method no longer supported',
4022 'Dataface noticed that the delegate class for the table "'.$this->tablename.
'" contains a tablePermissions() method. This method is no longer supported as of Dataface version 0.6. Please use the getPermissions() method instead with first parameter null to achieve the same results.
4024 function getPermissions(&$record, $params){
4025 if ( $record === null ){
4026 // return generic table permissions
4028 // return record-specific permissions
4031 array(
'table'=>$this->tablename)
4070 return array_keys($this->tabs());
4100 $del =& $this->getDelegate();
4101 if ( isset($del) and method_exists($del,
'__tabs__') ){
4102 $tabs = $del->__tabs__($record);
4104 foreach ($tabs as $tkey=>$tdata){
4105 $tabs[$tkey][
'order'] = $i++;
4110 $tabs = $this->_tabs;
4111 if ( isset($record) ){
4112 foreach ( $this->__join__($record) as
$tablename=>$tablelabel ){
4114 $tabs[
$tablename] = array(
'name'=>$tablename,
'label'=>$tablelabel,
'description'=>
'');
4119 foreach ($tabs as $tkey=>$tdata){
4120 $tabs[$tkey][
'order'] = $i++;
4134 $tabs =& $this->tabs($record);
4135 return $tabs[$tabname];
4156 $del =& $this->getDelegate();
4157 if ( isset($del) and method_exists($del,
'__join__') ){
4158 return $del->__join__($record);
4159 }
else if ( isset($this->_joinTables) ){
4160 return $this->_joinTables;
4178 return array_key_exists(
$tablename,$this->__join__($record));
4221 if ( !isset( $this->_fieldgroups[$fieldgroupname] ) ){
4222 $parent =& $this->getParent();
4223 if ( isset($parent) ){
4224 $fg =& $parent->getFieldgroup($fieldgroupname);
4227 return PEAR::raiseError(
"Attempt to get nonexistent field group '$fieldgroupname' from table '".$this->tablename.
"'\n<br>", E_USER_ERROR);
4229 return $this->_fieldgroups[$fieldgroupname];
4246 if ( !isset( $this->_cache[__FUNCTION__] ) ){
4247 $fg =& $this->_fieldgroups;
4248 $parent =& $this->getParent();
4249 if ( isset($parent) ){
4250 $fg = array_merge_recursive_unique($parent->getFieldgroups(), $fg);
4251 uasort($fg, array(&$this,
'_compareFields'));
4253 $this->_cache[__FUNCTION__] =& $fg;
4255 return $this->_cache[__FUNCTION__];
4282 import(
'Dataface/ImportFilter.php');
4283 if ( $this->_importFilters === null ){
4284 $this->_importFilters = array();
4292 $delegate =& $this->getDelegate();
4293 if ( $delegate !== null ) {
4294 $methods = get_class_methods(get_class( $delegate ) );
4295 foreach ( $methods as $method ){
4297 if ( preg_match(
'/^__import__(.*)$/', $method, $matches) ){
4298 $filter =
new Dataface_ImportFilter($this->tablename, $matches[1], df_translate(
'import_filters:'.$matches[1].
':label', ucwords(str_replace(
'_',
' ',$matches[1]))));
4299 $this->_importFilters[$matches[1]] =& $filter;
4305 $parent =& $this->getParent();
4306 if ( isset($parent) ){
4307 $this->_importFilters = array_merge($parent->getImportFilters(), $this->_importFilters);
4312 return $this->_importFilters;
4328 if (!is_a( $filter,
'Dataface_ImportFilter') ){
4329 throw new Exception(
"In Dataface_Table::registerImportFilter() 2nd argument expected to be of type 'Dataface_ImportFilter' but received '".get_class($filter).
"'. ", E_USER_ERROR);
4331 $filters =& $this->getImportFilters();
4332 $filters[$filter->name] =& $filter;
4348 $res = mysql_query(
"SHOW TABLES LIKE '".$this->tablename.
"__import_%'", $this->db);
4350 throw new Exception(
"Error getting import table list for table '".$this->tablename.
"'.", E_USER_ERROR);
4354 while ( $row = mysql_fetch_row($res) ){
4355 $tables[] = $row[0];
4357 mysql_free_result($res);
4371 import(
'Dataface/QueryBuilder.php');
4376 $this->cleanImportTables();
4378 $rand = rand(10000,999999);
4379 $name = $this->tablename.
'__import_'.strval(time()).
'_'.strval($rand);
4381 $res = mysql_query(
"CREATE TABLE `$name` SELECT * ".$qb->_from().
" LIMIT 0", $this->db);
4383 throw new Exception(
"Failed to create import table `$name` because a mysql error occurred: ".mysql_error($this->
db).
"\n", E_USER_ERROR);
4399 $tables = $this->getImportTables();
4401 $garbageLifetime =
$app->_conf[
'garbage_collector_threshold'];
4402 foreach ($tables as
$table){
4404 if ( preg_match(
'/^'.$this->tablename.
'__import_(\d+)_(\d)$/', $table, $matches) ){
4405 if ( time() - intval($matches[1]) > intval($garbageLifetime) ){
4406 $res = mysql_query(
"DROP TABLE `$table`", $this->
db);
4408 throw new Exception(
"Problem occurred attemtping to clean up old import table '$table'. MySQL returned an error: ".mysql_error($this->
db).
"\n", E_USER_ERROR);
4425 return preg_match(
'/^\w+__import_(\d{5,20})_(\d{4,10})$/',
$tablename);
4483 $filters =& $this->getImportFilters();
4484 $delegate =& $this->getDelegate();
4485 if ( $delegate === null ){
4495 if ( $importFilter === null ){
4500 foreach (array_keys($filters) as $filtername){
4501 $parsed =& $filters[$filtername]->import($data, $defaultValues);
4507 $errors[$filtername] =& $parsed;
4515 if ( isset($parsed) ){
4524 "No suitable import filter was found to import data into table '".$this->tablename.
"'. The following filters were attempted: {".implode(
',', array_keys($errors)).
"}."
4531 if ( !isset( $filters[$importFilter] ) ){
4532 return Dataface_Error::noImportFiltersFound(
"The import filter '".$importFilter.
"' was not found while attempting to import data into the table '".$this->tablename.
"'. The following import filters are available: {".implode(
',', array_keys($errors)).
"}."
4536 return $filters[$importFilter]->import($data, $defaultValues);
4562 function _parseINISection($section, &$curr){
4564 foreach ($section as $valuekey=>$valuevalue){
4565 if ( strpos($valuekey,
':') > 0 ){
4566 $path = explode(
':', $valuekey);
4568 for ( $i=0; $i<count(
$path); $i++){
4569 if ( $i<count(
$path)-1){
4570 if ( !isset($temp[
$path[$i]])) $temp[
$path[$i]] = array();
4571 $temp2 =& $temp[
$path[$i]];
4576 $temp[
$path[$i]] = $valuevalue;
4580 $curr[$valuekey] = $valuevalue;
4610 if ( !isset($this->_cache[__FUNCTION__][
$fieldname]) ){
4611 $field =& $this->getField($fieldname);
4620 if ( preg_match(
'/^([^\( ]+).*/', $type, $matches) ){
4621 $type = $matches[1];
4624 $type = trim($type);
4625 $this->_cache[__FUNCTION__][
$fieldname] = strtolower($type);
4628 return $this->_cache[__FUNCTION__][
$fieldname];
4644 return in_array( $type, array(
'date',
'datetime',
'time',
'timestamp') );
4655 return in_array( $this->getType(
$fieldname), array(
'blob',
'longblob',
'tinyblob',
'mediumblob') );
4668 return strtolower($this->getType(
$fieldname)) ==
'container';
4682 return (
$field[
'widget'][
'type'] ==
'password');
4691 return in_array( $this->getType(
$fieldname), array(
'text',
'longtext',
'tinytext',
'mediumtext') );
4703 return in_array( $fld[
'widget'][
'type'], array(
'table',
'group'));
4712 return in_array( $this->getType(
$fieldname), array(
'varchar',
'char') );
4721 return in_array(strtolower($this->getType(
$fieldname)), array(
'int',
'tinyint',
'mediumint',
'smallint',
'bigint'));
4731 return in_array(strtolower($this->getType(
$fieldname)), array(
'float',
'double',
'tinyfloat',
'mediumfloat',
'decimal'));
4763 return $this->parse_datetype($value);
4774 return $this->parse_datetype($value);
4791 if ( $value ==
'CURRENT_TIMESTAMP' ){
4792 $value = date(
'Y-m-d H:i:s');
4794 return $this->parse_datetype($value);
4803 return $this->parse_datetype($value);
4810 function isTimeStamp($value){
4812 return $converter->isTimestamp($value);
4819 function parse_datetype($value){
4855 $delegate =&
$table->getDelegate();
4857 if ( $delegate !== null and method_exists( $delegate, $rel_fieldname.
'__toString') ){
4858 $value = call_user_func( array(&$delegate, $rel_fieldname.
'__toString'), $value);
4862 if ( is_array($value) ){
4863 if ( method_exists( $this, $this->getType(
$fieldname).
"_to_string") ){
4864 $value = call_user_func( array( &$this, $this->getType(
$fieldname).
"_to_string"), $value );
4866 $value = implode(
', ', $value);
4869 $evt =
new stdClass;
4871 $evt->field =&
$table->getField($rel_fieldname);
4872 $evt->value = $value;
4873 $evt->type =
$table->getType($rel_fieldname);
4874 $this->app->fireEvent(
'after_getValueAsString', $evt);
4875 $value = $evt->value;
4907 $delegate =
$table->getDelegate();
4913 if ( isset($delegate) and method_exists($delegate, $method) ){
4914 return $delegate->$method($value);
4918 if ( isset(
$field[
'number_format']) ){
4919 $locale_data = localeconv();
4920 $decimal = $locale_data[
'decimal_point'];
4921 $sep = $locale_data[
'thousands_sep'];
4922 $places = intval(
$field[
'number_format']);
4923 $out = number_format(floatval(
$out), $places, $decimal, $sep);
4924 }
else if ( isset(
$field[
'money_format']) ){
4926 $fieldLocale = null;
4927 if ( method_exists($delegate,
'getFieldLocale') ){
4928 $fieldLocale = $delegate->getFieldLocale($this,
$fieldname);
4931 if ( !isset($fieldLocale) and @
$field[
'locale'] ){
4932 $fieldLocale = $field[
'locale'];
4935 if ( isset($fieldLocale) ){
4936 $oldLocale = setlocale(LC_MONETARY,
'0');
4937 if ( $oldLocale != $fieldLocale ){
4938 setlocale(LC_MONETARY, $fieldLocale);
4941 $out = money_format($field[
'money_format'], floatval(
$out));
4942 if ( isset($fieldLocale) ){
4943 setlocale(LC_MONETARY, $oldLocale);
4964 $fieldLocale = null;
4965 if ( method_exists($delegate,
'getFieldLocale') ){
4966 $fieldLocale = $delegate->getFieldLocale($this,
$fieldname);
4969 if ( !isset($fieldLocale) and @
$field[
'locale'] ){
4970 $fieldLocale = $field[
'locale'];
4973 if ( isset($fieldLocale) ){
4974 $oldLocale = setlocale(LC_TIME,
'0');
4975 if ( $oldLocale != $fieldLocale ){
4976 setlocale(LC_TIME, $fieldLocale);
4980 if ( isset($field[
'date_format']) ){
4981 $fmt = $field[
'date_format'];
4984 if ( !strtotime(
$out) )
return '';
4985 $out = strftime($fmt, strtotime(
$out));
4987 if ( isset($fieldLocale) ){
4988 setlocale(LC_TIME, $oldLocale);
4997 if ( isset(
$field[
'display_format']) ){
4998 if ( isset(
$field[
'display_format_i18n']) ){
4999 $fmt = df_translate(
$field[
'display_format_18n'],
$field[
'display_format']);
5001 $fmt =
$field[
'display_format'];
5026 throw new Exception(
$table->toString(), E_USER_ERROR);
5036 $delegate =& $this->getDelegate();
5037 if ( $delegate !== null and method_exists( $delegate,
$fieldname.
'__parse') ){
5038 $value = call_user_func( array( &$delegate,
$fieldname.
'__parse'), $value);
5046 else if ( method_exists( $this,
'parse_'.strtolower($type) ) ){
5048 $value = call_user_func( array(&$this,
'parse_'.strtolower($type)), $value);
5051 else if ( in_array(
$field[
'widget'][
'type'], array(
'group',
'table') ) and is_string($value) ){
5055 import(
'XML/Unserializer.php');
5056 $unserializer =
new XML_Unserializer();
5057 $parsed = $unserializer->unserialize($value);
5060 $value = $unserializer->getUnserializedData();
5070 $evt =
new stdClass;
5071 $evt->table = $this;
5073 $evt->value = $value;
5075 $evt->parseRepeat = $parseRepeat;
5076 $this->app->fireEvent(
'after_parse', $evt);
5077 $value = $evt->value;
5092 if ( !$separator ) $separator =
"\n";
5093 if ( !is_array($value) ){
5094 $value = explode($separator, $value);
5096 foreach (array_keys($value) as $key) {
5097 $value[$key] = $this->parse(
$fieldname, $value[$key],
false);
5111 function parseString( $str, $values ){
5112 if ( !is_string($str) )
return $str;
5114 $blackString = $str;
5115 while ( preg_match(
'/(?<!\\\)\$([0-9a-zA-Z\._\-]+)/', $blackString, $matches ) ){
5116 if ( $this->hasField($matches[1]) ){
5117 $replacement = $this->normalize($matches[1], $values[$matches[1]]);
5120 $replacement =
'\$0';
5122 $str = preg_replace(
'/(?<!\\\)\$'.$matches[1].
'/', $replacement, $str);
5123 $blackString = preg_replace(
'/(?<!\\\)\$'.$matches[1].
'/',
"", $blackString);
5144 if (
$field[
'widget'][
'type'] ==
'file' and is_uploaded_file(@$value[
'tmp_name']) and is_array($value)){
5149 if ( !is_array(@
$field[
'allowed_extensions']) and @
$field[
'allowed_extensions']){
5150 $field[
'allowed_extensions'] = explode(
',',@$field[
'allowed_extensions']);
5152 if ( !is_array(@$field[
'allowed_mimetypes']) and @$field[
'allowed_mimetypes'] ){
5153 $field[
'allowed_mimetypes'] = explode(
',',@$field[
'allowed_mimetypes']);
5155 if ( !is_array(@$field[
'disallowed_extensions']) and @$field[
'disallowed_extensions'] ){
5156 $field[
'disallowed_extensions'] = explode(
',',@$field[
'disallowed_extensions']);
5158 if ( !is_array(@$field[
'disallowed_mimetypes']) and @$field[
'disallowed_extensions']){
5159 $field[
'disallowed_mimetypes'] = explode(
',',@$field[
'disallowed_mimetypes']);
5162 $field[
'allowed_extensions'] = @array_map(
'strtolower', @$field[
'allowed_extensions']);
5163 $field[
'allowed_mimetypes'] = @array_map(
'strtolower', @$field[
'allowed_mimetypes']);
5164 $field[
'disallowed_extensions'] = @array_map(
'strtolower', @$field[
'disallowed_extensions']);
5165 $field[
'disallowed_mimetypes'] = @array_map(
'strtolower', @$field[
'disallowed_mimetypes']);
5168 if ( is_array( @$field[
'allowed_mimetypes'] ) and count($field[
'allowed_mimetypes']) > 0 ){
5169 if ( !in_array($value[
'type'], $field[
'allowed_mimetypes']) ){
5170 $params[
'message'] =
"The file submitted in field '".$field[
'name'].
"' is not the correct type. Received '".$value[
'type'].
"' but require one of (".implode(
',', $field[
'allowed_mimetypes']).
").";
5176 if ( @is_array(@$field[
'disallowed_mimetypes']) and in_array($value[
'type'], $field[
'disallowed_mimetypes']) ){
5177 $params[
'message'] =
"The file submitted in field '".$fieldname.
"' has a restricted mime type. The mime type received was '".$value[
'type'].
"'.";
5183 if ( preg_match(
'/\.([^\.]+)$/', $value[
'name'], $matches) ){
5184 $extension = $matches[1];
5186 $extension = strtolower($extension);
5189 if ( is_array( @$field[
'allowed_extensions'] ) and count($field[
'allowed_extensions']) > 0 ){
5190 if ( !in_array($extension, $field[
'allowed_extensions']) ){
5191 $params[
'message'] =
"The file submitted does not have the correct extension. Received file has extension '".$extension.
"' but the field requires either ".implode(
' or ', $field[
'allowed_extensions']).
".";
5197 if ( @is_array( @$field[
'disallowed_extensions'] ) and in_array($extension, $field[
'disallowed_extensions']) ){
5198 $params[
'message'] =
"The file submitted in field '".$fieldname.
"' has a restricted extension. Its extension was '".$extension.
"' which is disallowed for this form.";
5202 if ( @$field[
'max_size'] and intval($field[
'max_size']) < intval(@$value[
'size']) ){
5203 $params[
'message'] =
"The file submitted in field '".$fieldname.
"' is {$value['size']} bytes which exceeds the limit of {$field['max_size']} bytes for this field.";
5245 if ( @$this->app->_conf[
'debug'] ) echo
"<div class=\"debug_marker\">Block "$blockName"</div>";
5246 $delegate =& $this->getDelegate();
5254 if ( isset($this->app->_conf[
'_modules']) and count($this->app->_conf[
'_modules']) > 0){
5256 $mres = $mtool->displayBlock($blockName, $params);
5258 if ( isset($delegate) and method_exists($delegate,
'block__'.$blockName) ){
5259 $methodname =
'block__'.$blockName;
5260 $fres = $delegate->$methodname($params);
5266 $appDelegate =& $this->app->getDelegate();
5267 if (isset($appDelegate) and method_exists($appDelegate,
'block__'.$blockName) ){
5268 $methodname =
'block__'.$blockName;
5269 $fres = $appDelegate->$methodname($params);
5275 return ($res or $mres);
5287 $res = $this->displayBlock($blockName, $params);
5288 $out = ob_get_contents();
5290 if ( !$res )
return null;
5327 return df_get_record($this->tablename, $query);
5352 return DATAFACE_SITE_URL;
5358 private static $basePaths = array();
5363 if ( isset(self::$basePaths[
$table]) ){
5364 return self::$basePaths[
$table];
5366 return DATAFACE_SITE_PATH;
5376 function basePath(){
5378 return self::getBasePath($this->tablename);
5391 function getIniFile(){
5392 return $this->_iniFile;
5399 function setIniFile($file){
5400 $this->_iniFile = $file;
5412 $this->_cache = array();
5428 function date_to_string($value){
5440 if ( !isset( $this->_serializer ) ){
5444 return $this->_serializer;
5452 function datetime_to_string($value){
5501 import(
'Dataface/ActionTool.php');
5503 if ( !$this->_actionsLoaded ){
5504 $this->_actionsLoaded =
true;
5505 import(
'Dataface/ConfigTool.php');
5507 $actions =& $configTool->loadConfig(
'actions',$this->tablename);
5509 $singularLabel = $this->getSingularLabel();
5510 $pluralLabel = $this->getLabel();
5511 foreach ($actions as $key=>$action){
5513 $action[
'name'] = $key;
5514 if ( !isset($action[
'id']) ) $action[
'id'] = $action[
'name'];
5515 if ( !isset($action[
'label']) ) $action[
'label'] = str_replace(
'_',
' ',ucfirst($action[
'name']));
5516 if ( !isset($action[
'accessKey'])) $action[
'accessKey'] = substr($action[
'name'],0,1);
5517 if ( !isset($action[
'label_i18n']) ) $action[
'label_i18n'] =
'action:'.$action[
'name'].
' label';
5518 if ( !isset($action[
'description_i18n'])) $action[
'description_i18n'] =
'action:'.$action[
'name'].
' description';
5519 if ( isset($action[
'description']) ){
5520 $action[
'description'] = df_translate(
'actions.'.$action[
'name'].
'.description', $action[
'description'], array(
'table_label'=>$singularLabel,
'table_label_plural'=>$pluralLabel));
5522 if ( isset($action[
'label']) ){
5523 $action[
'label'] = df_translate(
'actions.'.$action[
'name'].
'.label',$action[
'label'], array(
'table_label_singular'=>$singularLabel,
'table_label_plural'=>$pluralLabel));
5526 $actionsTool->addAction($key, $action);
5533 if ( $noreturn )
return true;
5534 return $actionsTool->getActions($params);