Ejemplo n.º 1
0
 /**
  * Copy an object
  *
  * @param mixed &$source     MgdSchema object for reading the parameters
  * @param mixed &$parent      MgdSchema parent object
  * @param array $defaults
  * @return boolean Indicating success
  */
 public function copy_object(&$source, &$parent = null, $defaults = array())
 {
     // Resolve the source object
     self::resolve_object($source);
     // Duplicate the object
     $class_name = get_class($source);
     $target = new $class_name();
     $properties = $this->get_object_properties($source);
     // Copy the object properties
     foreach ($properties as $property) {
         // Skip certain fields
         if (preg_match('/^(_|metadata|guid|id)/', $property)) {
             continue;
         }
         $target->{$property} = $source->{$property};
     }
     // Override requested root object properties
     if (isset($this->target->guid) && $target->guid === $this->target->guid) {
         foreach ($this->root_object_values as $name => $value) {
             $target->{$name} = $value;
         }
     }
     // Override with defaults
     if ($defaults) {
         foreach ($defaults as $name => $value) {
             $target->{$name} = $value;
         }
     }
     $parent_property = $this->get_parent_property($source);
     // Copy the link to parent
     if ($parent) {
         self::resolve_object($parent);
         if (!$parent || !$parent->guid) {
             return false;
         }
         // @TODO: Is there a sure way to determine if the parent is
         // GUID or is it ID? If so, please change it here.
         if (is_string($source->{$parent_property})) {
             $parent_key = 'guid';
         } else {
             $parent_key = 'id';
         }
         $target->{$parent_property} = $parent->{$parent_key};
     } else {
         if (is_string($source->{$parent_property})) {
             $target->{$parent_property} = '';
         } else {
             $target->{$parent_property} = 0;
         }
     }
     $name_property = midcom_helper_reflector::get_name_property($target);
     $resolver = new midcom_helper_reflector_nameresolver($target);
     if (!empty($name_property) && !$resolver->name_is_safe_or_empty($name_property)) {
         debug_add('Source object ' . get_class($source) . " {$source->guid} has unsafe name, rewriting to safe form for the target", MIDCOM_LOG_WARN);
         $name_property = midcom_helper_reflector::get_name_property($target);
         if (empty($name_property)) {
             $this->errors[] = sprintf($this->_l10n->get('cannot fix unsafe name for source object %s, skipping'), get_class($source) . " {$source->guid}");
             return false;
         }
         $name_parts = explode('.', $target->{$name_property}, 2);
         if (isset($name_parts[1])) {
             $target->{$name_property} = midcom_helper_misc::generate_urlname_from_string($name_parts[0]) . ".{$name_parts[1]}";
             // Doublecheck safety and fall back if needed
             if (!$resolver->name_is_safe_or_empty()) {
                 $target->{$name_property} = midcom_helper_misc::generate_urlname_from_string($target->{$name_property});
             }
         } else {
             $target->{$name_property} = midcom_helper_misc::generate_urlname_from_string($target->{$name_property});
         }
         unset($name_parts, $name_property);
     }
     if ($this->allow_name_catenate && $name_property) {
         $name = $resolver->generate_unique_name();
         if ($name !== $target->{$name_property}) {
             $target->{$name_property} = $name;
         }
     }
     // This needs to be here, otherwise it will be overridden
     $target->allow_name_catenate = true;
     if (!$target->create()) {
         $this->errors[] = $this->_l10n->get('failed to create object: ' . mgd_errstr());
         return false;
     }
     // Store for later use - if ever needed
     $this->new_objects[] = $target;
     unset($name_property);
     // Copy parameters
     if (!$this->copy_parameters($source, $target) && $this->halt_on_errors) {
         $this->errors[] = $this->_l10n->get('failed to copy parameters');
         return false;
     }
     // Copy metadata
     if (!$this->copy_metadata($source, $target) && $this->halt_on_errors) {
         $this->errors[] = $this->_l10n->get('failed to copy metadata');
         return false;
     }
     // Copy attachments
     if (!$this->copy_attachments($source, $target) && $this->halt_on_errors) {
         $this->errors[] = $this->_l10n->get('failed to copy attachments');
         return false;
     }
     // Copy privileges
     if (!$this->copy_privileges($source, $target) && $this->halt_on_errors) {
         $this->errors[] = $this->_l10n->get('failed to copy privileges');
         return false;
     }
     return $target;
 }
Ejemplo n.º 2
0
 /**
  * Helper method to call in the _xxx_pre_checks, handles the API
  * level checks and automatic operations as specified in ticket #809
  *
  * @see http://trac.midgard-project.org/ticket/809
  * Quoting the ticket API-level section:
  * <pre>
  *      1. Checks will be done in the pre-flight check phase (ie just after _on_creating/_on_updating)
  *      2. If name is not unique false is returned for pre-flight check, preventing create/update
  *          2.2 UNLESS a property in the object ('allow_name_catenate') is set to true in which case unique one is generated by catenating an incrementing number to the name.
  *      3. if name is empty unique name is generated from title property (unless title is empty too)
  *      4. if name is not URL-safe false is returned
  * </pre>
  *
  * @param midcom_core_dbaobject $object The DBA object we're working on
  * @return boolean indicating whether from our point of view everything is ok
  *
  * @see midcom_helper_reflector_nameresolver::name_is_safe_or_empty()
  * @see midcom_helper_reflector_nameresolver::name_is_unique_or_empty()
  * @see midcom_helper_reflector_nameresolver::generate_unique_name()
  */
 private static function _pre_check_name(midcom_core_dbaobject $object)
 {
     // Make sure name is empty of unique if the object has such property
     $name_property = midcom_helper_reflector::get_name_property($object);
     if (empty($name_property)) {
         // This object has no name property, return early
         return true;
     }
     $resolver = new midcom_helper_reflector_nameresolver($object);
     /**
      * If name is empty, try to generate new, unique one
      *
      * @see http://trac.midgard-project.org/ticket/809
      */
     if (empty($object->{$name_property})) {
         // name is empty, try to generate
         $new_name = $resolver->generate_unique_name();
         if (!empty($new_name)) {
             $object->{$name_property} = $new_name;
         }
         unset($new_name);
     }
     /**
      * Enforce URL-safe (or empty) names
      *
      * @see http://trac.midgard-project.org/ticket/809
      */
     if (!$resolver->name_is_safe_or_empty()) {
         midcom_connection::set_error(MGD_ERR_INVALID_NAME);
         return false;
     }
     /**
      * Enforce unique (or empty) names
      *
      * @see http://trac.midgard-project.org/ticket/809
      */
     if (!$resolver->name_is_unique_or_empty()) {
         if ($object->allow_name_catenate) {
             // Transparent catenation allowed, let's try again.
             $new_name = $resolver->generate_unique_name();
             if (!empty($new_name)) {
                 $object->{$name_property} = $new_name;
                 return true;
             } else {
                 debug_add('allow_name_catenate was set but midcom_helper_reflector_nameresolver::generate_unique_name() returned empty value, falling through', MIDCOM_LOG_WARN);
             }
         }
         midcom_connection::set_error(MGD_ERR_OBJECT_NAME_EXISTS);
         return false;
     }
     // All checks ok, we're fine.
     return true;
 }