public static function get($id)
 {
     if (is_numeric($id)) {
         return self::$all[$id];
     }
     $id = train_case($id);
     try {
         constant('ContextEnum::' . $id);
         // Check constant exists
     } catch (ErrorException $e) {
         return null;
     }
     return $id;
 }
 public function Parameters()
 {
     $id_name = train_case(get_class($this)) . '_Id';
     return Parameter::join('Parameter_Attribution', 'Parameter.Id', '=', 'Parameter_Attribution.Parameter_Id')->where('Parameter_Attribution.' . $id_name, '=', $this->Id);
 }
 /**
  * Run the database seeds.
  *
  * @return void
  */
 public function run()
 {
     Eloquent::unguard();
     $parameterFields = ['name', 'type', 'widget', 'description', 'units', 'priority', 'restriction'];
     $attributionFields = ['Name', 'Type', 'Widget', 'Units'];
     $constantsXmls = File::allFiles(public_path() . '/constants');
     foreach ($constantsXmls as $constantsXml) {
         $dom = new DomDocument();
         $dom->load($constantsXml);
         $root = $dom->documentElement;
         $class = $root->getAttribute('class');
         $name = $root->getAttribute('name');
         //FIXME: Not very safe!
         if (Config::get('gosmart.context_as_enum') && $class == 'Context') {
             if ($root->hasAttribute('family')) {
                 $family = $root->getAttribute('family');
             } else {
                 $family = 'organ';
             }
             $target = Context::byNameFamily($name, $family);
         } else {
             $object = new $class();
             $objectQuery = $object->whereName($name);
             if ($root->hasAttribute('family')) {
                 $objectQuery = $objectQuery->whereFamily($root->getAttribute('family'));
             }
             $target = $objectQuery->first();
         }
         if (empty($target)) {
             throw new Exception("Did not find object {$name} ({$class}) for {$constantsXml}");
         }
         foreach ($root->childNodes as $constant) {
             if (get_class($constant) == 'DOMText') {
                 continue;
             }
             if (!$constant->hasAttribute('name')) {
                 throw new Exception("Constant missing name! ({$constantsXml})");
             }
             $present = array_filter($parameterFields, [$constant, 'hasAttribute']);
             $parameterData = [];
             array_map(function ($a) use(&$parameterData, $constant) {
                 $parameterData[train_case($a)] = $constant->getAttribute($a);
             }, $present);
             if (!$constant->hasAttribute('description')) {
                 $parameterData['Description'] = $parameterData['Name'];
             }
             $parameterData['Name'] = preg_replace('/[ -]/', '_', $parameterData['Name']);
             $parameterData['Name'] = strtoupper($constant->nodeName) . '_' . strtoupper(preg_replace('/[[:^word:]]/', '', $parameterData['Name']));
             if (!$constant->hasAttribute('type')) {
                 $parameterData['Type'] = 'float';
             }
             $parameter = Parameter::whereName($parameterData['Name'])->first();
             if (empty($parameter)) {
                 $parameter = Parameter::create($parameterData);
             } else {
                 $parameter->fill($parameterData)->save();
             }
             $id_name = train_case($class) . '_Id';
             if ($id_name == "Context_Id") {
                 $id_name = Context::$idField;
             }
             $attributionData = array_intersect_key($parameterData, array_flip($attributionFields));
             if ($constant->hasAttribute('context')) {
                 //$attributionData[Context::$idField] = Context::byNameFamily($constant->getAttribute('context'), $constant->getAttribute('contextFamily') ?: 'organ')->first()->id;
                 $context = Context::byNameFamily($constant->getAttribute('context'), $constant->getAttribute('contextFamily') ?: 'organ')->first();
             } else {
                 $context = null;
             }
             if ($constant->hasAttribute('value')) {
                 $attributionData['Value'] = $constant->getAttribute('value');
             } else {
                 $attributionData['Value'] = null;
             }
             $attribution = $target->attribute($attributionData, $context);
         }
     }
 }
 public function compileParameters($userSupplied, $needles, $needleUserParameters, &$incompatibilities = array(), &$userRequiredParameters)
 {
     if (is_array($needles)) {
         $needlesCollection = new Collection($needles);
     } else {
         $needlesCollection = $needles;
     }
     $disallowedNeedles = $needlesCollection->diff($this->Needles);
     foreach ($disallowedNeedles as $needle) {
         $incompatibilities[] = "Needle {$needle->Name} is not marked for use in this combination";
     }
     $allowedNeedles = $needlesCollection->intersect($this->Needles);
     $attributionsWithoutNeedle = ParameterAttribution::join("Parameter", "Parameter.Id", "=", "Parameter_Attribution.Parameter_Id")->addSelect("Parameter_Attribution.*", "Parameter.Name AS parameterName", "Parameter_Attribution.Value AS parameterValue");
     $automaticFields = array_diff($this->attributingFields, ['Protocol']);
     foreach ($automaticFields as $field) {
         $property = train_case($field);
         $class = get_class($this->{$property});
         $attributionsWithoutNeedle = $attributionsWithoutNeedle->where(function ($q) use($field, $property, $class) {
             $q->whereNull($class::$idField)->orWhere($class::$idField, "=", $this->{$property}->Id);
         });
     }
     $resultList = new Collection();
     if (in_array('Protocol', $this->attributingFields)) {
         $resultList = $resultList->merge($this->Protocol->Algorithms->lists('Result'));
     }
     foreach ($this->Protocol->Algorithms as $algorithm) {
         $algorithms = $this->Protocol->Algorithms;
         $attributionsWithoutNeedle = $attributionsWithoutNeedle->where(function ($q) use($algorithms) {
             $q->whereNull("Algorithm_Id");
             foreach ($algorithms as $algorithm) {
                 $q->orWhere("Algorithm_Id", "=", $algorithm->Id);
             }
         });
     }
     $needleParametersByNeedle = [];
     if (count($allowedNeedles)) {
         foreach ($needlesCollection as $needleIx => $needle) {
             if (!in_array($needle, $allowedNeedles->all())) {
                 continue;
             }
             $attributions = with(clone $attributionsWithoutNeedle)->where(function ($q) use($needle) {
                 $q = $q->whereNull("Needle_Id");
                 $q = $q->orWhere("Needle_Id", "=", $needle->Id);
             });
             $requirements = with(clone $attributions)->whereNull("Parameter_Attribution.Value");
             $supplies = with(clone $attributions)->whereNotNull("Parameter_Attribution.Value");
             $needleParameters = [];
             foreach ($supplies->get() as $a) {
                 $name = $a->Parameter->Name;
                 if (!isset($needleParameters[$name])) {
                     $needleParameters[$name] = [];
                 }
                 $needleParameters[$name][] = $a;
             }
             array_walk($needleParameters, function (&$v, $name) {
                 /* Remove any redundant parameters - only needle parameters and parameters
                  * overriding a needle-specific parameter count */
                 if (!count(array_filter($v, function ($n) {
                     return $n->Needle_Id !== null;
                 }))) {
                     $v = false;
                 } else {
                     $v = $this->chooseAttribution($v);
                 }
             });
             $needleParameters = array_filter($needleParameters);
             $needleUser = isset($needleUserParameters[$needleIx]) ? $needleUserParameters[$needleIx] : [];
             foreach ($needleUser as $needleUserParameter) {
                 $needleParameters[$needleUserParameter->Name] = $needleUserParameter;
             }
             $needleParametersByNeedle[$needleIx] = $needleParameters;
             $requirementsList = $requirements->lists("parameterName");
             $supplyList = $supplies->lists("parameterName");
             $needleUserSupplied = [];
             if (isset($needleUserParameters[$needleIx])) {
                 $needleUserSupplied = $needleUserParameters[$needleIx]->lists('Name');
             }
             $undefinedList = array_diff($requirementsList, $supplyList, $needleUserSupplied, $userSupplied->lists('Name'));
             $undefinedList = array_diff($undefinedList, $resultList->lists("Name"));
             if (!empty($undefinedList)) {
                 $requirementsMap = array_combine($requirements->lists("parameterName"), $requirements->get()->all());
                 foreach ($undefinedList as $missingParameterName) {
                     $editable = $requirementsMap[$missingParameterName]->Editable >= 2;
                     if ($editable) {
                         $userRequiredParameters[] = $requirementsMap[$missingParameterName]->Parameter;
                     } else {
                         $incompatibilities[] = "Parameter {$missingParameterName} is missing";
                     }
                 }
             }
         }
     } else {
         $requirements = with(clone $attributionsWithoutNeedle)->whereNull("Parameter_Attribution.Value");
         $supplies = with(clone $attributionsWithoutNeedle)->whereNotNull("Parameter_Attribution.Value");
         $requirementsList = $requirements->lists("parameterName");
         $supplyList = $supplies->lists("parameterName");
         $undefinedList = array_diff($requirementsList, $supplyList, $userSupplied->lists('Name'));
         $undefinedList = array_diff($undefinedList, $resultList->lists("Name"));
         if (!empty($undefinedList)) {
             $requirementsMap = array_combine($requirements->lists("parameterName"), $requirements->get()->all());
             foreach ($undefinedList as $missingParameterName) {
                 $editable = $requirementsMap[$missingParameterName]->Editable >= 2;
                 if ($editable) {
                     $userRequiredParameters[] = $requirementsMap[$missingParameterName]->Parameter;
                 } else {
                     $incompatibilities[] = "Parameter {$missingParameterName} is missing";
                 }
             }
         }
     }
     $supplies = $attributionsWithoutNeedle->whereNull("Needle_Id")->whereNotNull("Parameter_Attribution.Value");
     $attributions = [];
     foreach ($supplies->get() as $attribution) {
         $name = $attribution->Parameter->Name;
         if (!isset($attributions[$name])) {
             $attributions[$name] = [];
         }
         $attributions[$name][] = $attribution;
     }
     $parameters = [];
     foreach ($attributions as $name => $available) {
         $parameters[$name] = $this->chooseAttribution($available);
     }
     foreach ($userSupplied as $userParameter) {
         if ($userParameter->Value === null) {
             $userParameter->Value = $userParameter->pivot->ValueSet;
         }
         $parameters[$userParameter->Name] = $userParameter;
     }
     foreach ($parameters as $parameter) {
         if ($parameter->Editable == 3) {
             /* Always editable */
             $userRequiredParameters[] = $parameter;
         }
     }
     foreach ($needleParametersByNeedle as $needle => $needleParameters) {
         foreach ($needleParameters as $parameter) {
             if ($parameter->Editable == 3) {
                 /* Always editable */
                 $userRequiredParameters[] = $parameter;
             }
         }
     }
     return [$parameters, $needleParametersByNeedle];
 }
 public function activeFields()
 {
     return array_filter($this->specifyingFields, function ($field) {
         $fieldName = train_case($field) . "_Id";
         return $this->{$fieldName};
     });
 }