|
|
|
@@ -1,9 +1,9 @@
|
|
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* CLass: MindProcessor 1.0
|
|
|
|
|
* Class used to interpret and generate wml code
|
|
|
|
|
* @package processor
|
|
|
|
|
* Definition: class used to interpret and generate wml code
|
|
|
|
|
* Author: Felipe Nascimento
|
|
|
|
|
* @author Felipe Nascimento
|
|
|
|
|
*
|
|
|
|
|
* Observations:
|
|
|
|
|
* * tables without relations (neither pointed by nor pointing to other tables) will not exist
|
|
|
|
@@ -51,6 +51,7 @@
|
|
|
|
|
'max'=>' ||"||MIND_QUANTIFY_MAX_MAX||"|| '));
|
|
|
|
|
/**
|
|
|
|
|
* This method receives the text and parses it into an Array with all the expressions, separeted by "." or ";"
|
|
|
|
|
* @author Felipe Nascimento
|
|
|
|
|
* @name parse
|
|
|
|
|
* @param String $str
|
|
|
|
|
* @return numeric Array
|
|
|
|
@@ -60,16 +61,18 @@
|
|
|
|
|
$expressions= Array(); // will have all the expressions to be interpreted
|
|
|
|
|
$sep= Array('.', ';'); // expression separator
|
|
|
|
|
$str= preg_split('//', trim($str)); // separing comments
|
|
|
|
|
$str[]= $sep[0];
|
|
|
|
|
$inside= false;
|
|
|
|
|
$str[]= $sep[0]; // this will fix well the expressiona had a comment without a . in the end
|
|
|
|
|
$inside= false; // indicates whether the iterator is between ""
|
|
|
|
|
$comment= false;
|
|
|
|
|
$allow= false;
|
|
|
|
|
$insideAtt= false;
|
|
|
|
|
$allow= false; // this var indicates if the iterator is between {} or []
|
|
|
|
|
$insideAtt= false; // inside ( ) ??
|
|
|
|
|
$currentExpression= '';
|
|
|
|
|
|
|
|
|
|
// running through the string, letter by letter
|
|
|
|
|
for($i=0, $j= sizeof($str); $i<$j; $i++)
|
|
|
|
|
{
|
|
|
|
|
$letter= $str[$i];
|
|
|
|
|
// first, we gotta ignore the comment blocks
|
|
|
|
|
if($letter == '/')
|
|
|
|
|
{
|
|
|
|
|
if(!$comment)
|
|
|
|
@@ -86,9 +89,11 @@
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if it is inside a comment block, we skip to the next letter
|
|
|
|
|
if($comment)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// checking if it is scaping the next charachter, if so, we must add this and skip
|
|
|
|
|
if($i>0 && $str[$i-1] == '\\')
|
|
|
|
|
{
|
|
|
|
|
$currentExpression.= $str[$i];
|
|
|
|
@@ -124,28 +129,33 @@
|
|
|
|
|
}
|
|
|
|
|
return $expressions;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* This is the constructor
|
|
|
|
|
* if it receives a project object by parameter, it processes this project, otherwise, it simply returns itself
|
|
|
|
|
* with its current properties
|
|
|
|
|
* @author Felipe Nascimento
|
|
|
|
|
* @name __construct
|
|
|
|
|
* @param [Project Object]
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function __construct($project=false) // obj of project
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function log($level, $msg)
|
|
|
|
|
{
|
|
|
|
|
if(!$project){
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
$this->messages[]= Array(4, "Starting...");
|
|
|
|
|
$this->messages[]= Array($level, $msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This method has the responsability to understand (interpret) the code... this is the core
|
|
|
|
|
* @author Felipe Nascimento
|
|
|
|
|
* @name process
|
|
|
|
|
* @param [Project Object]
|
|
|
|
|
* @return MindProcessor Object
|
|
|
|
|
*/
|
|
|
|
|
private function process($project)
|
|
|
|
|
{
|
|
|
|
|
// again, we will use the global _MIND to have all the properties and methods as a singleton
|
|
|
|
|
GLOBAL $_MIND;
|
|
|
|
|
// lets log each step
|
|
|
|
|
$this->log(4, "Starting...");
|
|
|
|
|
|
|
|
|
|
// loading the language class, the interface and the selected idiom
|
|
|
|
|
$langDir= $_MIND['rootDir'].$_MIND['languageDir'].'/';
|
|
|
|
|
|
|
|
|
|
include($langDir.'language.php');
|
|
|
|
|
|
|
|
|
|
$lang= new Language($project->lang);
|
|
|
|
|
|
|
|
|
|
// two different classes we're gonna need here
|
|
|
|
|
include('table.php');
|
|
|
|
|
include('relation.php');
|
|
|
|
|
|
|
|
|
@@ -153,14 +163,19 @@
|
|
|
|
|
$this->fixedChars= $lang->fixedChars;
|
|
|
|
|
|
|
|
|
|
// identifying structures / subTypess
|
|
|
|
|
// e.g.: $sex:char(1, {F=Female|M=Male}).
|
|
|
|
|
$regExp= '\$\w[a-z0-9_]+:\w.+\)';
|
|
|
|
|
$this->sentences= preg_match_all('/'.$regExp.'/i', $project->wml, $matches);
|
|
|
|
|
// if there are subtypes, we will create a temp table to keep them
|
|
|
|
|
// we have to log it, too, and then parse it, as it was a simple attribute
|
|
|
|
|
if(sizeof($matches[0]) > 0)
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$this->theWebMindLanguageTempTable]= new Table($this->theWebMindLanguageTempTable);
|
|
|
|
|
|
|
|
|
|
$matches= $matches[0];
|
|
|
|
|
$this->messages[]= Array(4, "Identifying subtypes...");
|
|
|
|
|
$this->log(4, "Identifying subtypes...");
|
|
|
|
|
// here, we will use all the identified subtypes, replacing with them in
|
|
|
|
|
// the lines where they were being used
|
|
|
|
|
for($i=0; $i<sizeof($matches); $i++)
|
|
|
|
|
{
|
|
|
|
|
$subTypesName= trim(substr($matches[$i], 1, strpos($matches[$i], ':')-1));
|
|
|
|
@@ -172,8 +187,11 @@
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->messages[]= Array(4, "Analysing expressions...");
|
|
|
|
|
$this->log(4, "Analysing expressions...");
|
|
|
|
|
// here, we gotta parse our prepared sentences
|
|
|
|
|
// from now on, $this->sentences will be an array with each expression, already patternized
|
|
|
|
|
$this->sentences= $this->parse($project->wml);
|
|
|
|
|
// let's keep a copy of these sentences, before starting to change them
|
|
|
|
|
$originalSentences= $this->sentences;
|
|
|
|
|
|
|
|
|
|
// identify the "belong's
|
|
|
|
@@ -191,34 +209,44 @@
|
|
|
|
|
// identify the unique fields
|
|
|
|
|
$regExp= trim(implode('|', $lang->unique));
|
|
|
|
|
$this->sentences= preg_replace('/'.$regExp.'/i', $this->unique, $this->sentences);
|
|
|
|
|
|
|
|
|
|
// applying fieldtypes
|
|
|
|
|
reset($this->types);
|
|
|
|
|
$this->messages[]= Array(4, "Specifying attributes");
|
|
|
|
|
$this->log(4, "Specifying attributes");
|
|
|
|
|
while($cur= current($this->types))
|
|
|
|
|
{
|
|
|
|
|
if(isset($lang->types[$cur]))
|
|
|
|
|
if(is_array($lang->types[$cur]))
|
|
|
|
|
{
|
|
|
|
|
// first of all, we have to prepare our regular expression
|
|
|
|
|
$regExp= trim(implode('|', $lang->types[$cur]));
|
|
|
|
|
$regExp= str_replace('|', '\(|:', $regExp);
|
|
|
|
|
// and then, apply it to the sentences
|
|
|
|
|
// the result will be a code following theWebMind's rules
|
|
|
|
|
$this->sentences= preg_replace('/:'.$regExp.'/i', ':'.$cur.'(', $this->sentences);
|
|
|
|
|
}
|
|
|
|
|
next($this->types);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the same will be done here, to identify the quantifiers identificators (like "or", for example)
|
|
|
|
|
$regExp= trim(implode('|', $lang->quantifiersId));
|
|
|
|
|
$this->sentences= preg_replace('/'.$regExp.'/i', $this->quantifierId, $this->sentences, 0);
|
|
|
|
|
|
|
|
|
|
$this->tmpSentences= $this->sentences;
|
|
|
|
|
|
|
|
|
|
// now, we will use a copy of the sentences, and will clean the array used before
|
|
|
|
|
$s= sizeof($this->tmpSentences);
|
|
|
|
|
$this->sentences= false;
|
|
|
|
|
$this->sentences= Array();
|
|
|
|
|
|
|
|
|
|
// preparing quantifiers regular expressions
|
|
|
|
|
$regExpQmm= (trim(implode('|', $lang->quantifiers['min']['min'])));
|
|
|
|
|
$regExpQmM= (trim(implode('|', $lang->quantifiers['min']['max'])));
|
|
|
|
|
$regExpQMm= (trim(implode('|', $lang->quantifiers['max']['min'])));
|
|
|
|
|
$regExpQMM= (trim(implode('|', $lang->quantifiers['max']['max'])));
|
|
|
|
|
$regExpQ= trim(implode('|', $lang->quantifiersId));
|
|
|
|
|
|
|
|
|
|
// let's iterate all the expressions
|
|
|
|
|
// $s was used to "cache" the size during the loop
|
|
|
|
|
$this->currentLine= 0;
|
|
|
|
|
for($i=0; $i<$s; $i++)
|
|
|
|
|
{
|
|
|
|
@@ -228,6 +256,13 @@
|
|
|
|
|
$extends= false;
|
|
|
|
|
$abstract= false;
|
|
|
|
|
|
|
|
|
|
// the verbs are the key... let's work with them, before continuing
|
|
|
|
|
/*
|
|
|
|
|
* There are three main verb types
|
|
|
|
|
* the possessive, mandatory and relational
|
|
|
|
|
* These possibilities are represented as VERB, BELONG and OBLIGATION and
|
|
|
|
|
* depending on them, Mind will decide how to deal with each relation
|
|
|
|
|
*/
|
|
|
|
|
if(trim($this->tmpSentences[$i]) != '' && preg_match('/'.preg_quote($this->verbId).'/', $this->tmpSentences[$i]))
|
|
|
|
|
{
|
|
|
|
|
$continue= true;
|
|
|
|
@@ -242,12 +277,17 @@
|
|
|
|
|
}else{
|
|
|
|
|
if(trim($this->currentLine) != '')
|
|
|
|
|
{
|
|
|
|
|
$this->messages[]= Array(3, "Expression with no known verb:<img src='images/engine.gif' align='right' style='cursor:poniter;' alt='Specify the verb manually' title='Specify the verb manually' onclick='Mind.Project.AddVerb(event, this);'/><br/><i> \"" . $this->currentLine."\"</i>");
|
|
|
|
|
$this->log(3, "Expression with no known verb:<img src='images/engine.gif' align='right' style='cursor:poniter;'".
|
|
|
|
|
"alt='Specify the verb manually' title='Specify the verb manually' onclick='Mind.Project.AddVerb(event, ".
|
|
|
|
|
"this);'/><br/><i> \"".
|
|
|
|
|
$this->currentLine."\"</i>");
|
|
|
|
|
$this->warnings++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// if a verb was found
|
|
|
|
|
if($continue)
|
|
|
|
|
{
|
|
|
|
|
// we have to divide the expression by two using the verb
|
|
|
|
|
$curExpression= explode($this->verbId, $this->tmpSentences[$i]);
|
|
|
|
|
if(sizeOf($curExpression)==1)
|
|
|
|
|
$curExpression= explode($this->belongsId, $this->tmpSentences[$i]);
|
|
|
|
@@ -258,42 +298,52 @@
|
|
|
|
|
$delimiter= strrpos(trim($curExpression[0]), ' ');
|
|
|
|
|
if(!$delimiter) $delimiter= 0;
|
|
|
|
|
$curExpression[0]= trim(substr($curExpression[0], $delimiter, strlen($curExpression[0])-$delimiter)); // got the left entity
|
|
|
|
|
// defining if it has an attribute or another entity
|
|
|
|
|
|
|
|
|
|
$regExp= implode('|', $this->types);
|
|
|
|
|
$regExp= str_replace('|', '\(|', $regExp);
|
|
|
|
|
|
|
|
|
|
//print_r($curExpression);
|
|
|
|
|
/*
|
|
|
|
|
* from now, the $curExpression has in the first half,
|
|
|
|
|
* the left table, and in the second, the definition of
|
|
|
|
|
* an attribute or another entity
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// if there is not a second half, it means the only matched verb was the last valid word
|
|
|
|
|
// then, we will skip this expression
|
|
|
|
|
if(!isset($curExpression[1]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
$regExp= implode('|', $this->types);
|
|
|
|
|
$regExp= str_replace('|', '\(|', $regExp);
|
|
|
|
|
$ext= '';
|
|
|
|
|
// is this and attribute or what?
|
|
|
|
|
if(preg_match('/:'.$regExp.'/', $curExpression[1], $matches))
|
|
|
|
|
{ // it is an attribute
|
|
|
|
|
{
|
|
|
|
|
// this is an attribute
|
|
|
|
|
$matches= $matches[0];
|
|
|
|
|
}else{
|
|
|
|
|
// no, this is "what"
|
|
|
|
|
$ext= ($abstract)? $this->obligationId: (($extends)? $this->belongsId: '');
|
|
|
|
|
$curExpression[1]= preg_replace('/ ('.$regExpQ.') /i', $this->quantifierId, $curExpression[1], 1);
|
|
|
|
|
|
|
|
|
|
$curExpression[1]= preg_split('/'.preg_quote($this->quantifierId).'/', $curExpression[1]);
|
|
|
|
|
|
|
|
|
|
if(sizeof($curExpression[1]) == 1) // had not an OR statemant, then, the minimum quantifier is aplied
|
|
|
|
|
if(sizeof($curExpression[1]) == 1)
|
|
|
|
|
{
|
|
|
|
|
// had not an OR statemant, then, the minimum quantifier is aplied
|
|
|
|
|
$curExpression[1]= $this->quantifiers['min']['min'].$this->quantifierId.$curExpression[1][0];
|
|
|
|
|
else{
|
|
|
|
|
}else{
|
|
|
|
|
$exp= '/^( +)?('.$regExpQmm.')/i';
|
|
|
|
|
$curExpression[1][0]= preg_replace($exp, $this->quantifiers['min']['min'], $curExpression[1][0]);
|
|
|
|
|
$exp= '/^( +)?('.$regExpQmM.')/i';
|
|
|
|
|
$curExpression[1][0]= preg_replace($exp, $this->quantifiers['min']['max'], $curExpression[1][0], 1);
|
|
|
|
|
|
|
|
|
|
$curExpression[1]= implode($this->quantifierId, $curExpression[1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$exp= '/ ('.$regExpQMm.') /i';
|
|
|
|
|
$curExpression[1]= preg_replace($exp, $this->quantifiers['max']['min'], $curExpression[1], 1);
|
|
|
|
|
$exp= '/ ('.$regExpQMM.') /i';
|
|
|
|
|
$curExpression[1]= preg_replace($exp, $this->quantifiers['max']['max'], $curExpression[1], 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let's use only the word next to the delimiter, as the riht entity's name
|
|
|
|
|
// let's use only the word next to the delimiter, as the right entity's name
|
|
|
|
|
if(strpos($curExpression[1], $this->quantifierId)) // if it is not an attribute definition
|
|
|
|
|
{
|
|
|
|
|
if(strpos($curExpression[1], $this->quantifiers['max']['min']))
|
|
|
|
@@ -307,28 +357,28 @@
|
|
|
|
|
$curExpression[1]= str_replace($this->quantifierId, $this->quantifierId.$this->quantifiers['max']['max'], $curExpression[1]);
|
|
|
|
|
$sharp= $this->quantifiers['max']['max'];
|
|
|
|
|
}
|
|
|
|
|
//echo $curExpression[1].'<hr>';
|
|
|
|
|
$curExpression[1] = explode($sharp, $curExpression[1]);
|
|
|
|
|
$curExpression[1][1]= explode(' ', trim($curExpression[1][1]));
|
|
|
|
|
//echo '<pre>'; print_r($curExpression[1][1]);
|
|
|
|
|
$curExpression[1][1]= $curExpression[1][1][0];
|
|
|
|
|
$curExpression[1] = implode($sharp, $curExpression[1]);
|
|
|
|
|
}
|
|
|
|
|
/**/
|
|
|
|
|
|
|
|
|
|
$curExpression= implode($this->verbId.$ext, $curExpression);
|
|
|
|
|
$this->sentences[]= $curExpression;
|
|
|
|
|
$this->execExpression($curExpression);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$this->messages[]= Array(4, "Treating cardinalities");
|
|
|
|
|
$this->log(4, "Treating cardinalities");
|
|
|
|
|
reset($this->relations);
|
|
|
|
|
|
|
|
|
|
$rels= Array(); // final array of valid relations
|
|
|
|
|
// now, we gotta use only the valid tables and relations
|
|
|
|
|
$rels= Array(); // this is going to be the final array of valid relations
|
|
|
|
|
$tables= Array();
|
|
|
|
|
|
|
|
|
|
while($rel= current($this->relations))
|
|
|
|
|
{
|
|
|
|
|
// here, we will check if already exists a relation between these entities, in opposite directions
|
|
|
|
|
// if it does exist, AND the relation here is N, then this is a N/N relation between these entities
|
|
|
|
|
if(isset($this->relations[$rel->rightTable.'|'.$rel->leftTable]) && $rel->max== 'n')
|
|
|
|
|
{
|
|
|
|
|
$tmpTable= $rel->leftTable.'_'.$rel->rightTable;
|
|
|
|
@@ -339,6 +389,9 @@
|
|
|
|
|
$this->tables[$rel->leftTable]->refered[]= $tmpRelation;
|
|
|
|
|
$this->tables[$rel->leftTable]->weight++;
|
|
|
|
|
|
|
|
|
|
// we have to create a new table to link both entities
|
|
|
|
|
// and also, two new relations
|
|
|
|
|
|
|
|
|
|
$tmpRelation= $rel->rightTable.'|'.$tmpTable;
|
|
|
|
|
$rels[$tmpRelation]= new Relation($tmpRelation);
|
|
|
|
|
$rels[$tmpRelation]->min= 0;
|
|
|
|
@@ -356,17 +409,21 @@
|
|
|
|
|
else{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->messages[]= Array(2, "Relation n/n between \"".$rel->leftTable."\" and \"".$rel->rightTable."\". I have to create a new table, \"".$tmpTable."\", to link them.");
|
|
|
|
|
$this->log(2, "Relation n/n between \"".$rel->leftTable.
|
|
|
|
|
"\" and \"".$rel->rightTable.
|
|
|
|
|
"\". I have to create a new table, \"".$tmpTable.
|
|
|
|
|
"\", to link them.");
|
|
|
|
|
|
|
|
|
|
$tables[$tmpTable]->addForeignKey($rel->leftTable);
|
|
|
|
|
$tables[$tmpTable]->addForeignKey($rel->rightTable);
|
|
|
|
|
|
|
|
|
|
// after that, we must remove the old relation between these two entities
|
|
|
|
|
$tables[$rel->rightTable]->removeForeignKey($rel->leftTable);
|
|
|
|
|
$tables[$rel->leftTable]->removeForeignKey($rel->rightTable);
|
|
|
|
|
unset($this->relations[$rel->rightTable.'|'.$rel->leftTable]);
|
|
|
|
|
}else{ // n/1 or 1/n or 1/1 => OK
|
|
|
|
|
}else{ // n/1 or 1/n or 1/1
|
|
|
|
|
$rels[$rel->name]= $rel;
|
|
|
|
|
|
|
|
|
|
// here, we have a commom relation between tables
|
|
|
|
|
if(!isset($tables[$rel->leftTable]))
|
|
|
|
|
$tables[$rel->leftTable]= $this->tables[$rel->leftTable];
|
|
|
|
|
if(!isset($tables[$rel->rightTable]))
|
|
|
|
@@ -380,13 +437,16 @@
|
|
|
|
|
}
|
|
|
|
|
next($this->relations);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(sizeof($tables) == 0)
|
|
|
|
|
{
|
|
|
|
|
$this->messages[]= Array(0, "There are no entities in your project!");
|
|
|
|
|
$this->messages[]= Array(2, "Is the project running with the correct idiom?");
|
|
|
|
|
$this->messages[]= Array(2, "You can check if you haven't forgoten any \".\" or \";\" in the end of any line.");
|
|
|
|
|
$this->log(0, "There are no entities in your project!");
|
|
|
|
|
$this->log(2, "Is the project running with the correct idiom?");
|
|
|
|
|
$this->log(2, "You can check if you haven't forgoten any \".\" or \";\" in the end of any line.");
|
|
|
|
|
$this->errors++;
|
|
|
|
|
}else{
|
|
|
|
|
// here, any table that neither is pointed by nor points to another table will be removed
|
|
|
|
|
// it only happens if, of course, the size of tables decreased after the analysis
|
|
|
|
|
if(sizeof($this->tables) > sizeof($tables))
|
|
|
|
|
{
|
|
|
|
|
reset($tables);
|
|
|
|
@@ -394,7 +454,9 @@
|
|
|
|
|
{
|
|
|
|
|
if(!isset($tables[$table->name]) && $table->name != $this->theWebMindLanguageTempTable)
|
|
|
|
|
{
|
|
|
|
|
$this->messages[]= Array(3, '"'.$table->name.'" has no relation with any other entity. I will ignore it and will not create any "floating" table for it, or any output.');
|
|
|
|
|
$this->log(3, '"'.$table->name.
|
|
|
|
|
'" has no relation with any other entity. I will ignore it and will not '.
|
|
|
|
|
'create any "floating" table for it, or any output.');
|
|
|
|
|
$this->warnings++;
|
|
|
|
|
}
|
|
|
|
|
next($this->tables);
|
|
|
|
@@ -402,19 +464,25 @@
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// now, we update the real table list
|
|
|
|
|
$this->tables= $tables;
|
|
|
|
|
$this->relations= $rels;
|
|
|
|
|
|
|
|
|
|
// we have to treat the 1/1 relations
|
|
|
|
|
reset($this->relations);
|
|
|
|
|
while($rel= current($this->relations))
|
|
|
|
|
{
|
|
|
|
|
if(isset($this->relations[$rel->rightTable.'|'.$rel->leftTable]))
|
|
|
|
|
{
|
|
|
|
|
if($rel->max == '1') // 1/1
|
|
|
|
|
// if there is a relation as specified with the last if and the current relation has the
|
|
|
|
|
// maximum of 1, then the relation is obviously 1/1
|
|
|
|
|
if($rel->max == '1')
|
|
|
|
|
{
|
|
|
|
|
// in this case, we will, for default, put one of the tables in evidence (the one which is more relevant to the application)
|
|
|
|
|
$evidence= &$this->tables[(($this->tables[$rel->leftTable]->weight > $this->tables[$rel->rightTable]->weight)? $rel->leftTable: $rel->rightTable)];
|
|
|
|
|
$other= &$this->tables[(($evidence->name == $rel->leftTable)? $rel->rightTable: $rel->leftTable)];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// then, the less relevant will have its atrtributes moved to the evidenced one
|
|
|
|
|
if(!isset($this->relations[$rel->leftTable.'|'.$rel->leftTable]) && $rel->rightTable != $rel->leftTable)
|
|
|
|
|
{
|
|
|
|
|
foreach($other->attributes as $att)
|
|
|
|
@@ -422,7 +490,9 @@
|
|
|
|
|
$att->name= $other->name.'_'.$att->name;
|
|
|
|
|
$evidence->attributes[$att->name]= $att;
|
|
|
|
|
}
|
|
|
|
|
// remove the relations between the evidenced table and the table that will be removed
|
|
|
|
|
|
|
|
|
|
// also, any relation this less relevant entity had must be moved to the other table
|
|
|
|
|
// (both, those which point to it, and those which point from it)
|
|
|
|
|
$other->refered= preg_replace('/'.$other->name.'/', $evidence->name, $other->refered);
|
|
|
|
|
$evidence->refered= array_merge($evidence->refered, $other->refered);
|
|
|
|
|
|
|
|
|
@@ -437,7 +507,7 @@
|
|
|
|
|
$evidence->removeForeignKey($other->name);
|
|
|
|
|
$other->removeReference($evidence->name.'|'.$evidence->name);
|
|
|
|
|
|
|
|
|
|
// fixing the tables pointed by the table that no longer exist
|
|
|
|
|
// fixing the tables pointed by the table that no longer exists
|
|
|
|
|
foreach($other->foreignKeys as $fk)
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$fk[1]]->refered= preg_replace('/'.$other->name.'/', $evidence->name, $this->tables[$fk[1]]->refered);
|
|
|
|
@@ -445,14 +515,12 @@
|
|
|
|
|
$this->tables[$fk[1]]->removeReference($fk[1].'|'.$other->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fixing the tables that were pointing to the table that no longer exist
|
|
|
|
|
// fixing the tables that were pointing to the table that no longer exists
|
|
|
|
|
foreach($other->refered as $ref)
|
|
|
|
|
{
|
|
|
|
|
$ref= explode('|', $ref);
|
|
|
|
|
$ref= $ref[1];
|
|
|
|
|
|
|
|
|
|
//echo '<pre>'; print_r($ref);
|
|
|
|
|
|
|
|
|
|
if(is_array($this->tables[$ref]->foreignKeys))
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$ref]->foreignKeys[0]= preg_replace('/'.$other->name.'/', $evidence->name, $this->tables[$ref]->foreignKeys[0]);
|
|
|
|
@@ -462,9 +530,10 @@
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// removing the table 'other', and the relations 1/1
|
|
|
|
|
$this->messages[]= Array(3, "Relation 1/1. The table <i>\"".$other->name.'"</i> has been removed. Its attributes were moved to "'.$rel->rightTable);
|
|
|
|
|
$this->log(3, "Relation 1/1. The table <i>\"".
|
|
|
|
|
$other->name.'"</i> has been removed. Its attributes were moved to "'.
|
|
|
|
|
$rel->rightTable);
|
|
|
|
|
$this->warnings++;
|
|
|
|
|
unset($this->tables[$other->name]);
|
|
|
|
|
unset($this->relations[$rel->leftTable.'|'.$rel->rightTable]);
|
|
|
|
@@ -475,6 +544,8 @@
|
|
|
|
|
next($this->relations);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// here, we will add to each table a primary key, as set in the choosen DBMS configuration
|
|
|
|
|
$this->log(4, "Dealing with Primary Keys");
|
|
|
|
|
reset($this->tables);
|
|
|
|
|
while($tab= current($this->tables))
|
|
|
|
|
{
|
|
|
|
@@ -489,11 +560,17 @@
|
|
|
|
|
$tmpAtt= $this->tables[$tab->name]->attributes;
|
|
|
|
|
$att= $this->tables[$tab->name]->addAttribute($att);
|
|
|
|
|
$this->tables[$tab->name]->attributes= array_merge(Array($att->name=>$att), $tmpAtt);
|
|
|
|
|
|
|
|
|
|
next($this->tables);
|
|
|
|
|
}
|
|
|
|
|
$this->messages[]= Array(4, "Exporting format to theWebMind's knowledge format");
|
|
|
|
|
// formating in WebMindLanguage (wml format)
|
|
|
|
|
|
|
|
|
|
$this->log(4, "Exporting format to theWebMind's knowledge format");
|
|
|
|
|
/* formating in WebMindLanguage (wml format)
|
|
|
|
|
* this is not being used YET... the idea is to build a "knowledge base center" with the main structure of many
|
|
|
|
|
* projects as people contribute to it. In the end, people will be able to start a project
|
|
|
|
|
* by its subject, loading automaticaly what most of the projects with that subject had
|
|
|
|
|
* I want to add some semanthic to it, and also the ability to learn with this base of knowledge
|
|
|
|
|
* Of course, any help is VERY welcome to reach this goal, too :)
|
|
|
|
|
*/
|
|
|
|
|
$this->verbId = trim(str_replace('|', '\|', $this->verbId));
|
|
|
|
|
$this->required = trim(str_replace('|', '\|', $this->required));
|
|
|
|
|
$this->quantifierId = trim(str_replace('|', '\|', $this->quantifierId));
|
|
|
|
@@ -509,24 +586,48 @@
|
|
|
|
|
$this->sentences= preg_replace('/'.trim($this->quantifiers['max']['max']).'/', '*}', $this->sentences);
|
|
|
|
|
$this->sentences= preg_replace('/'.trim($this->required).'/', 'not null', $this->sentences);
|
|
|
|
|
$this->sentences= preg_replace('/,( *)/', ',', $this->sentences);
|
|
|
|
|
// this structure, presented above is unders construction and may suffer modification
|
|
|
|
|
|
|
|
|
|
// here, we have to clear the mess and organize the house
|
|
|
|
|
$project->wml= trim(implode('
|
|
|
|
|
', $this->sentences));
|
|
|
|
|
$this->processedWML= '';
|
|
|
|
|
$this->tmpSentences= '';
|
|
|
|
|
$this->debug['status']= 1;
|
|
|
|
|
|
|
|
|
|
// messaging the end of the action, with its status
|
|
|
|
|
if($this->warnings == 0 && $this->errors == 0)
|
|
|
|
|
$this->messages[]= Array(1, "Final Status: Finished with no errors");
|
|
|
|
|
$this->log(1, "Final Status: Finished with no errors");
|
|
|
|
|
elseif($this->errors == 0)
|
|
|
|
|
{
|
|
|
|
|
$this->messages[]= Array(1, "Final Status: Finished with ".$this->warnings." warnings");
|
|
|
|
|
$this->log(1, "Final Status: Finished with ".$this->warnings." warnings");
|
|
|
|
|
}else{
|
|
|
|
|
$this->messages[]= Array(0, "<b>Final Status: Failed with ".$this->warnings." warning(s) and ".$this->errors.' error(s)</b>');
|
|
|
|
|
$this->log(0, "<b>Final Status: Failed with ".$this->warnings.
|
|
|
|
|
" warning(s) and ".$this->errors.' error(s)</b>');
|
|
|
|
|
}
|
|
|
|
|
$this->debug['messages']= $this->messages;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This is the constructor
|
|
|
|
|
* if it receives a project object by parameter, it processes this project, otherwise, it simply returns itself
|
|
|
|
|
* with its current properties
|
|
|
|
|
* @author Felipe Nascimento
|
|
|
|
|
* @name __construct
|
|
|
|
|
* @param [Project Object]
|
|
|
|
|
* @return MindProcessor Object
|
|
|
|
|
*/
|
|
|
|
|
public function __construct($project=false) // obj of project
|
|
|
|
|
{
|
|
|
|
|
// if no project has been received, we simply return the new empty Object
|
|
|
|
|
if(!$project){
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if a project Object has been sent to this method, then process it and return its result
|
|
|
|
|
return $this->process($project);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Get method to return the list of currently supported types
|
|
|
|
|
* @author Felipe Nascimento
|
|
|
|
@@ -589,44 +690,63 @@
|
|
|
|
|
*/
|
|
|
|
|
private function execExpression($mindExp)
|
|
|
|
|
{
|
|
|
|
|
// using the global _MIND to have access to its properties
|
|
|
|
|
GLOBAL $_MIND;
|
|
|
|
|
// keeping the original sentence, before changing it
|
|
|
|
|
$original_sentence= $mindExp;
|
|
|
|
|
|
|
|
|
|
if(strpos($mindExp, $this->quantifierId)) // it means it is a table relation
|
|
|
|
|
// let's check if it is a table relation
|
|
|
|
|
if(strpos($mindExp, $this->quantifierId))
|
|
|
|
|
{
|
|
|
|
|
// starting some variables
|
|
|
|
|
$selfReference= false;
|
|
|
|
|
$abstractLeftTable= false;
|
|
|
|
|
$abstractRightTable= false;
|
|
|
|
|
$oneByOneSelfRelation= false;
|
|
|
|
|
|
|
|
|
|
// here, everything we have is the important/useful part of the instruction
|
|
|
|
|
// in this case, we can do the following without fear
|
|
|
|
|
$mindExp= explode(' ', trim($mindExp));
|
|
|
|
|
|
|
|
|
|
// on a table relation, the first word is the left table
|
|
|
|
|
$leftTable= $this->filter(trim($mindExp[0]));
|
|
|
|
|
// and the left word is the secont entity
|
|
|
|
|
$rightTable= $this->filter(trim($mindExp[sizeof($mindExp)-1]));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* if the name of right table has a ":" it means it is probably an attribute
|
|
|
|
|
* wrote with some mistake
|
|
|
|
|
* in this case, we will alert the developer about it
|
|
|
|
|
*/
|
|
|
|
|
if($pos = strpos($rightTable,':'))
|
|
|
|
|
{
|
|
|
|
|
$newTmpName= substr($rightTable, 0, $pos);
|
|
|
|
|
$tmpType= substr($rightTable, $pos+1, strpos($rightTable, '(') - ($pos+1));
|
|
|
|
|
$this->messages[]= Array(3, "Entity \"".$rightTable."\" renamed to \"".$newTmpName."\".".
|
|
|
|
|
"<img src='images/engine.gif' align='right' style='cursor:poniter;' alt='Add \"".$tmpType."\" as a type' title='Add \"".$tmpType."\" as a type'".
|
|
|
|
|
" onclick='Mind.Project.AddType(event, \"".$tmpType."\", ".JSON_encode($this->types).");'/>".
|
|
|
|
|
"<br/>I believe it should be a property, right? But I couldn't identify the type \"".$tmpType."\"!");
|
|
|
|
|
$this->log(3, "Entity \"".$rightTable."\" renamed to \"".$newTmpName."\".".
|
|
|
|
|
"<img src='images/engine.gif' align='right' style='cursor:poniter;' alt='Add \"".$tmpType.
|
|
|
|
|
"\" as a type' title='Add \"".$tmpType."\" as a type'".
|
|
|
|
|
" onclick='Mind.Project.AddType(event, \"".$tmpType."\", ".JSON_encode($this->types).");'/>".
|
|
|
|
|
"<br/>I believe it should be a property, right? But I couldn't identify the type \"".$tmpType."\"!");
|
|
|
|
|
// anyways... we will fix the name to a valid one
|
|
|
|
|
$rightTable= $newTmpName;
|
|
|
|
|
$this->warnings++;
|
|
|
|
|
//continue;
|
|
|
|
|
}
|
|
|
|
|
if($leftTable == $rightTable) // entity that points to itself
|
|
|
|
|
// here, we find those entities which point to themselves
|
|
|
|
|
if($leftTable == $rightTable)
|
|
|
|
|
{
|
|
|
|
|
// acording to its cardinality, it destroys the righttable, or create another table
|
|
|
|
|
// to implement the relation
|
|
|
|
|
if(in_array(trim($this->quantifiers['max']['min']), $mindExp))
|
|
|
|
|
{
|
|
|
|
|
$rightTable= false;
|
|
|
|
|
}else{
|
|
|
|
|
$rightTable= $rightTable.'_pointer';
|
|
|
|
|
$rightTable= $rightTable.$_MIND['selfRelationalTable'];
|
|
|
|
|
}
|
|
|
|
|
$selfReference= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// verify if the current entity is set to be abstract
|
|
|
|
|
// verify if the current entity was set manually to be abstract
|
|
|
|
|
if(substr($leftTable, 0, 1) == '#')
|
|
|
|
|
{
|
|
|
|
|
$abstractLeftTable= true;
|
|
|
|
@@ -640,20 +760,17 @@
|
|
|
|
|
$rightTable= preg_replace('/^#/', '', $rightTable);
|
|
|
|
|
}
|
|
|
|
|
if(!isset($this->tables[$rightTable]))
|
|
|
|
|
{ // the same with both entities
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$rightTable]= new Table($rightTable);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// verifies if the entity does not exist, yet
|
|
|
|
|
if(!isset($this->tables[$leftTable]))
|
|
|
|
|
{ // then, creat it
|
|
|
|
|
{
|
|
|
|
|
// then, creat it
|
|
|
|
|
$this->tables[$leftTable]= new Table($leftTable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if($abstractLeftTable)
|
|
|
|
|
$this->tables[$leftTable]->abstract= true;
|
|
|
|
|
|
|
|
|
|
if(!$rightTable)
|
|
|
|
|
{
|
|
|
|
|
if(!isset($this->relations[$leftTable.'|'.$leftTable]))
|
|
|
|
@@ -664,7 +781,7 @@
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let's see if this entity should extend another one
|
|
|
|
|
//echo implode(',', $mindExp).'\n </br/>';
|
|
|
|
|
// it depends on the type of verb, used to identify the relation
|
|
|
|
|
if($rightTable && preg_match('/'.preg_quote(trim($this->obligationId)).'/', implode(',', $mindExp)) > 0)
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$leftTable]->extends= $rightTable;
|
|
|
|
@@ -674,26 +791,35 @@
|
|
|
|
|
if($rightTable && preg_match('/'.preg_quote(trim($this->belongsId)).'/', implode(',', $mindExp)) > 0)
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$rightTable]->extends= $leftTable;
|
|
|
|
|
//$this->tables[$rightTable]->abstract= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// are they abstract?
|
|
|
|
|
if($abstractLeftTable)
|
|
|
|
|
$this->tables[$leftTable]->abstract= true;
|
|
|
|
|
if($abstractRightTable)
|
|
|
|
|
$this->tables[$rightTable]->abstract= true;
|
|
|
|
|
|
|
|
|
|
// treating cardinalities
|
|
|
|
|
$min= (in_array(trim($this->quantifiers['min']['min']), $mindExp))? '0': '1';
|
|
|
|
|
$max= (in_array(trim($this->quantifiers['max']['min']), $mindExp))? '1': 'n';
|
|
|
|
|
|
|
|
|
|
// deciding for the name this relation will have
|
|
|
|
|
if($rightTable)
|
|
|
|
|
$relName= ($max=='n')? $leftTable.'|'.$rightTable: $rightTable.'|'.$leftTable;
|
|
|
|
|
else
|
|
|
|
|
$relName= false;
|
|
|
|
|
|
|
|
|
|
// in case of self reference
|
|
|
|
|
if($selfReference)
|
|
|
|
|
{
|
|
|
|
|
// if it is not 1/1 to the same table
|
|
|
|
|
if(!$oneByOneSelfRelation)
|
|
|
|
|
{
|
|
|
|
|
if(!isset($this->relations[$relName]))
|
|
|
|
|
{
|
|
|
|
|
$att= new Attribute('main_'.$leftTable);
|
|
|
|
|
// we have to create a new table, and point it to the first one twice
|
|
|
|
|
// one to the current ID, and another to the reference
|
|
|
|
|
$att= new Attribute($_MIND['parentOnSelfRelation'].$leftTable);
|
|
|
|
|
$att->required= 1;
|
|
|
|
|
$att->unique= 0;
|
|
|
|
|
$att->type= 'integer';
|
|
|
|
@@ -705,79 +831,95 @@
|
|
|
|
|
$this->tables[$rightTable]->addAttribute($att);
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
// otherwise, Mind simply needs to have the first table referencing itself
|
|
|
|
|
$this->tables[$leftTable]->addForeignKey($leftTable);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dealing with the the relation between entities
|
|
|
|
|
|
|
|
|
|
// creating the new relation
|
|
|
|
|
if($relName)
|
|
|
|
|
{
|
|
|
|
|
$this->relations[$relName]= new Relation($relName);
|
|
|
|
|
$this->relations[$relName]->min= $min;
|
|
|
|
|
$this->relations[$relName]->max= $max;
|
|
|
|
|
}
|
|
|
|
|
}else{ // attributes
|
|
|
|
|
}else{ // this is an attribute
|
|
|
|
|
$mindExp= explode(trim($this->verbId), $mindExp);
|
|
|
|
|
// firstly, we gotta create the left table, if it does not exist
|
|
|
|
|
$leftTable= $this->filter(trim($mindExp[0]));
|
|
|
|
|
if(!isset($this->tables[$leftTable]))
|
|
|
|
|
{
|
|
|
|
|
$this->tables[$leftTable]= new Table($leftTable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// here, we will divide the attribute name of the rest
|
|
|
|
|
$mindExp= explode(':', $mindExp[1], 2);
|
|
|
|
|
$attName= explode(' ', trim($mindExp[0]));
|
|
|
|
|
$attName= $attName[sizeof($attName)-1];
|
|
|
|
|
|
|
|
|
|
if(!isset($mindExp[1]))
|
|
|
|
|
{
|
|
|
|
|
trigger_error('Undefined verb in the sentence: <b>'. $this->currentLine.'</b> at line <b>'. $this->currentLineNumber .'</b>',
|
|
|
|
|
E_USER_WARNING);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let's parse the atribute properties
|
|
|
|
|
$mindExp= explode('(', $mindExp[1], 2);
|
|
|
|
|
$att= new Attribute($this->filter($attName));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Notice that, each property we set, must be removed from the
|
|
|
|
|
* expression, to not be processed twice
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// attributes with # will set as hidden, to the module
|
|
|
|
|
if(substr($att->name, 0,1) == '#')
|
|
|
|
|
{
|
|
|
|
|
$att->hidden= true;
|
|
|
|
|
$att->name= preg_replace('/^#/', '', $att->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(strpos($mindExp[1], trim($this->required))) // if it's a required field
|
|
|
|
|
// Is this a required field?
|
|
|
|
|
if(strpos($mindExp[1], trim($this->required)))
|
|
|
|
|
{
|
|
|
|
|
$mindExp[1]= str_replace(trim($this->required), '', $mindExp[1]);
|
|
|
|
|
$att->required= 1;
|
|
|
|
|
}else{
|
|
|
|
|
$att->required= 0;
|
|
|
|
|
}
|
|
|
|
|
if(strpos($mindExp[1], trim($this->unique))) // if it's unique
|
|
|
|
|
|
|
|
|
|
// is it unique?
|
|
|
|
|
if(strpos($mindExp[1], trim($this->unique)))
|
|
|
|
|
{
|
|
|
|
|
$mindExp[1]= str_replace(trim($this->unique), '', $mindExp[1]);
|
|
|
|
|
$att->unique= 1;
|
|
|
|
|
}else{
|
|
|
|
|
$att->unique= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// the type is the word which is before "("
|
|
|
|
|
$att->type= trim($mindExp[0]);
|
|
|
|
|
|
|
|
|
|
preg_match('/([^(\\\)])?"(.*)[^(\\\)]"/', preg_replace('/\)/', ') ', $mindExp[1]), $matches); // get the default value to the current attribute ( between "" )
|
|
|
|
|
// Let's get the default value to the current attribute ( between "" )
|
|
|
|
|
preg_match('/([^(\\\)])?"(.*)[^(\\\)]"/', preg_replace('/\)/', ') ', $mindExp[1]), $matches);
|
|
|
|
|
if(sizeof($matches)>0)
|
|
|
|
|
{
|
|
|
|
|
// if it does have a default value, we have to prepare it
|
|
|
|
|
$att->defaultValue= addslashes(preg_replace('/^("|.")|"$/', '', trim($matches[0])));
|
|
|
|
|
|
|
|
|
|
// default values may be executable, the "Exec:" keyword is required, then
|
|
|
|
|
if(substr($att->defaultValue, 0, 5) != "Exec:")
|
|
|
|
|
$att->defaultValue= "'".trim($att->defaultValue)."'";
|
|
|
|
|
else
|
|
|
|
|
$att->defaultValue= preg_replace('/^Exec:/', '', trim($att->defaultValue));
|
|
|
|
|
|
|
|
|
|
// removing the default value
|
|
|
|
|
$mindExp[1]= str_replace($matches[0], '', $mindExp[1]);
|
|
|
|
|
}
|
|
|
|
|
preg_match('/[^(\\\)]\[(.*)[^(\\\)]\]/', $mindExp[1], $matches); // get the mask for attribute ( betwee [] )
|
|
|
|
|
|
|
|
|
|
// checking for masks ( between [ ] )
|
|
|
|
|
preg_match('/[^(\\\)]\[(.*)[^(\\\)]\]/', $mindExp[1], $matches);
|
|
|
|
|
if(sizeof($matches)>0)
|
|
|
|
|
{
|
|
|
|
|
$mindExp[1]= str_replace($matches[0], '', $mindExp[1]);
|
|
|
|
|
$att->mask= preg_replace('/^(\[|.\[)|\]$/', '', trim($matches[0]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// looking for comments the attribute have (identified by the use of // )
|
|
|
|
|
preg_match('/\/\/.*$/', $mindExp[1], $matches);
|
|
|
|
|
if(sizeof($matches)>0)
|
|
|
|
|
{
|
|
|
|
@@ -785,25 +927,35 @@
|
|
|
|
|
$att->comment= $matches[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
preg_match('/[^(\\\)]\{(.*)[^(\\\)]\}/', $mindExp[1], $matches); // get the options for attribute ( between {} )
|
|
|
|
|
// get the options for attribute ( between { } )
|
|
|
|
|
preg_match('/[^(\\\)]\{(.*)[^(\\\)]\}/', $mindExp[1], $matches);
|
|
|
|
|
if(sizeof($matches)>0)
|
|
|
|
|
{
|
|
|
|
|
/* if there are valid options, we have to parse them
|
|
|
|
|
* the pattern is just like this:
|
|
|
|
|
* code=label|anotherCode=AnotherLabel
|
|
|
|
|
* E.g.: {F=Female|M=Male}
|
|
|
|
|
*/
|
|
|
|
|
$matches[0]= preg_replace('/^(\{|.\{)|\}$/', '', trim($matches[0]));
|
|
|
|
|
$mindExp[1]= str_replace($matches[0], '', $mindExp[1]);
|
|
|
|
|
|
|
|
|
|
$matches= preg_split('/(\|)/', $matches[0]); // parses the options, separated by |, using = to especify any value/label
|
|
|
|
|
$matches= preg_split('/(\|)/', $matches[0]);
|
|
|
|
|
$att->options= $matches;
|
|
|
|
|
for($i=0; $i<sizeof($att->options);$i++)
|
|
|
|
|
{
|
|
|
|
|
$att->options[$i]= explode('=', $att->options[$i], 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// te attribute size is the number that rested, parsed as real
|
|
|
|
|
$att->size= (real)$mindExp[1];
|
|
|
|
|
|
|
|
|
|
// finally, add the attribute to the global list of attributes and also to the current table
|
|
|
|
|
// if the same attribute was already used, with the same characteristics, we tell the developer
|
|
|
|
|
if(isset($this->globalAttributeList[$att->name]) && $this->globalAttributeList[$att->name] == $att)
|
|
|
|
|
$this->messages[]= Array(2, "Attribute \"".$att->name."\" used more than one time, with the same carachteristics.<br/>Aren't they the same property? You could set both in the same table, or in a new table creating an agreggation.");
|
|
|
|
|
$this->log(2, "Attribute \"".$att->name."\" used more than one time, with the same carachteristics.<br/>Aren't they the same property? You could set both in the same table, or in a new table creating an agreggation.");
|
|
|
|
|
$this->globalAttributeList[$att->name]= $att;
|
|
|
|
|
$this->tables[$leftTable]->addAttribute($att);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|
|
|
|
|