Add Advanced Related Objects

@since 2.3.0
353256
public function add_related_objects() {

		PodsField_Pick::$related_objects['table'] = array(
			'label' => __( 'Database Tables', 'pods' ),
			'group' => __( 'Advanced Objects', 'pods' ),
		);

		if ( is_multisite() ) {
			PodsField_Pick::$related_objects['site'] = array(
				'label' => __( 'Multisite Sites', 'pods' ),
				'group' => __( 'Advanced Objects', 'pods' ),
			);

			PodsField_Pick::$related_objects['network'] = array(
				'label' => __( 'Multisite Networks', 'pods' ),
				'group' => __( 'Advanced Objects', 'pods' ),
			);
		}

		PodsField_Pick::$related_objects['theme'] = array(
			'label'         => __( 'Themes', 'pods' ),
			'group'         => __( 'Advanced Objects', 'pods' ),
			'simple'        => true,
			'data_callback' => array( $this, 'data_themes' ),
		);

		PodsField_Pick::$related_objects['page-template'] = array(
			'label'         => __( 'Page Templates', 'pods' ),
			'group'         => __( 'Advanced Objects', 'pods' ),
			'simple'        => true,
			'data_callback' => array( $this, 'data_page_templates' ),
		);

		PodsField_Pick::$related_objects['sidebar'] = array(
			'label'         => __( 'Sidebars', 'pods' ),
			'group'         => __( 'Advanced Objects', 'pods' ),
			'simple'        => true,
			'data_callback' => array( $this, 'data_sidebars' ),
		);

		PodsField_Pick::$related_objects['post-types'] = array(
			'label'         => __( 'Post Type Objects', 'pods' ),
			'group'         => __( 'Advanced Objects', 'pods' ),
			'simple'        => true,
			'data_callback' => array( $this, 'data_post_types' ),
		);

		PodsField_Pick::$related_objects['taxonomies'] = array(
			'label'         => __( 'Taxonomy Objects', 'pods' ),
			'group'         => __( 'Advanced Objects', 'pods' ),
			'simple'        => true,
			'data_callback' => array( $this, 'data_taxonomies' ),
		);
	}
589043
function(instance, relatedObject, options) {
    var opts = _.defaults({}, options, { follow: true, attrs: true });
    var inverse = opts.follow && relatedObject[this.inverse + 'Relation'];

    if (opts.attrs) {
      // set the foreign key property as well
      instance.setAttribute(this.foreignKeyAttr, undefined);
    }

    this._setRelated(instance, undefined);

    if (inverse) {
      inverse.disassociate(relatedObject, instance, _.extend({}, options, {
        follow: false,
      }));
    }
  }
882132
public function add_objects( $type, array $objects, $parent = null ) {
		foreach ( $objects as $slug => $struct ) {
			if ( is_array( $struct ) ) {
				$this->add( $type, $slug, $struct, $parent );
			}
		}
	}
159289
public function addAttrArticle()
    {
        $aAddArticle = $this->_getActionIds('oxarticles.oxid');
        $soxId = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('synchoxid');

        // adding
        if (\OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('all')) {
            $sArticleTable = $this->_getViewName('oxarticles');
            $aAddArticle = $this->_getAll($this->_addFilter("select $sArticleTable.oxid " . $this->_getQuery()));
        }

        $oAttribute = oxNew(\OxidEsales\Eshop\Application\Model\Attribute::class);

        if ($oAttribute->load($soxId) && is_array($aAddArticle)) {
            foreach ($aAddArticle as $sAdd) {
                $oNewGroup = oxNew(\OxidEsales\Eshop\Core\Model\BaseModel::class);
                $oNewGroup->init("oxobject2attribute");
                $oNewGroup->oxobject2attribute__oxobjectid = new \OxidEsales\Eshop\Core\Field($sAdd);
                $oNewGroup->oxobject2attribute__oxattrid = new \OxidEsales\Eshop\Core\Field($oAttribute->oxattribute__oxid->value);
                $oNewGroup->save();

                $this->onArticleAddToAttributeList($sAdd);
            }
        }
    }
809913
private void addRelations(List<RelationHolder> rlHolders, Map<String, Object> values)
    {
        if (rlHolders != null)
        {
            for (RelationHolder relation : rlHolders)
            {
                values.put(relation.getRelationName(), relation.getRelationValue());
            }
        }
    }
239433
private function add_relationships($post_type)
    {
        if (! empty($this->taxonomies)) {
            $filters = [];

            foreach ($this->taxonomies as $k => $v) {
                // Add all taxonomies to $filters unless explicitly declared otherwise.
                if (\is_integer($k)) {
                    $post_type->taxonomy($v);
                    $filters[] = $v;
                    continue;
                }

                if ($v === false) {
                    $post_type->taxonomy($k);
                }
            }

            $post_type->filters($filters);
        }
    }
1291990
def add_classes(relations)
      relations.each do |cls|
        extract(cls[:doc]).each_with_index do |ex, i|
          @examples << {
            :id => cls[:name] + "-" + i.to_s,
            :name => cls[:name] + " example #" + (i+1).to_s,
            :href => '#!/api/' + cls[:name],
            :code => ex[:code],
            :options => ex[:options],
          }
        end
      end

      self
    end
195637
def _create_related(self, obj, related, subfield_dict):
        
        for field, items in related.items():
            subobjects = []
            all_subrelated = []
            Subtype, reverse_id_field, subsubdict = subfield_dict[field]
            for order, item in enumerate(items):
                # pull off 'subrelated' (things that are related to this obj)
                subrelated = {}
                for subfield in subsubdict:
                    subrelated[subfield] = item.pop(subfield)

                if field in self.preserve_order:
                    item['order'] = order

                item[reverse_id_field] = obj.id

                try:
                    subobjects.append(Subtype(**item))
                    all_subrelated.append(subrelated)
                except Exception as e:
                    raise DataImportError('{} while importing {} as {}'.format(e, item, Subtype))

            # add all subobjects at once (really great for actions & votes)
            try:
                Subtype.objects.bulk_create(subobjects)
            except Exception as e:
                raise DataImportError('{} while importing {} as {}'.format(e, subobjects, Subtype))

            # after import the subobjects, import their subsubobjects
            for subobj, subrel in zip(subobjects, all_subrelated):
                self._create_related(subobj, subrel, subsubdict)
519130
public function add_associations($unused = null) {

        if ($unused !== null) {
            debugging('Illegal argument used in blog_entry->add_associations()', DEBUG_DEVELOPER);
        }

        $this->remove_associations();

        if (!empty($this->courseassoc)) {
            $this->add_association($this->courseassoc);
        }

        if (!empty($this->modassoc)) {
            $this->add_association($this->modassoc);
        }
    }
420059
def add_objects!(objects, request_options = {})
      res = add_objects(objects, request_options)
      wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
      res
    end
542925
protected function addAttributes()
    {
        if ($this->props['tagOnly']) {
            return;
        }
        if ($this->props['attribs']['required']) {
            $this->classAdd($this->props['attribsContainer'], 'required');
        }
        if (!$this->props['isValid']) {
            $this->classAdd($this->props['attribsContainer'], 'has-error');
            if ($this->props['invalidReason']) {
                $this->props['helpBlock'] = $this->props['invalidReason'];
            }
        }
        if ($this->props['helpBlock']) {
            // we don't want aria-describedby attrib when tagOnly
            $this->props['attribs']['aria-describedby'] = $this->props['attribsHelpBlock']['id'];
        }
    }
1353240
def add_relations(self, relations):
        """"""
        for source, destination in relations:
            self.add_relation(source, destination)
763322
public function afterFind()
    {
        /** @var ActiveRecord $owner */
        $owner = $this->owner;

        if ($owner->isRelationPopulated('translations') && $related = $owner->getRelatedRecords()['translations']) {
            $translations = $this->indexByLanguage($related);
            foreach ($this->_languageKeys as $language) {
                foreach ($this->attributes as $attribute) {
                    foreach ($translations as $translation) {
                        if ($translation->{$this->languageField} == $language) {
                            $attributeName = $this->localizedPrefix . $attribute;
                            $this->setMultilingualAttribute($this->getAttributeName($attribute, $language), $translation->{$attributeName});
                        }
                    }
                }
            }
        } else if ($owner->getAttribute($this->_ownerPrimaryKey) !== null) {
            if (!$owner->isRelationPopulated('translation')) {
                $owner->translation;
            }

            $translation = $owner->getRelatedRecords()['translation'];
            if ($translation) {
                foreach ($this->attributes as $attribute) {
                    $attribute_name = $this->localizedPrefix . $attribute;
                    $owner->setMultilingualAttribute($attribute, $translation->$attribute_name);
                }
            }
        }

        foreach ($this->attributes as $attribute) {
            if ($owner->hasAttribute($attribute) && $this->getMultilingualAttribute($attribute)) {
                $owner->setAttribute($attribute, $this->getMultilingualAttribute($attribute));
            }
        }
    }
1310278
public function setup_related_objects( $force = false ) {

		$new_data_loaded = false;

		if ( ! $force && empty( self::$related_objects ) ) {
			// Only load transient if we aren't forcing a refresh.
			self::$related_objects = pods_transient_get( 'pods_related_objects' );

			if ( false !== self::$related_objects ) {
				$new_data_loaded = true;
			}
		} elseif ( $force ) {
			// If we are rebuilding, make sure we start with a clean slate.
			self::$related_objects = array();
		}

		if ( empty( self::$related_objects ) ) {
			// Do a complete build of related_objects.
			$new_data_loaded = true;

			// Custom simple relationship lists.
			self::$related_objects['custom-simple'] = array(
				'label'  => __( 'Simple (custom defined list)', 'pods' ),
				'group'  => __( 'Custom', 'pods' ),
				'simple' => true,
			);

			// Pods options.
			$pod_options = array();

			// Include PodsMeta if not already included.
			pods_meta();

			// Advanced Content Types for relationships.
			$_pods = PodsMeta::$advanced_content_types;

			foreach ( $_pods as $pod ) {
				$pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')';
			}

			// Settings pods for relationships.
			$_pods = PodsMeta::$settings;

			foreach ( $_pods as $pod ) {
				$pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')';
			}

			asort( $pod_options );

			foreach ( $pod_options as $pod => $label ) {
				self::$related_objects[ 'pod-' . $pod ] = array(
					'label'         => $label,
					'group'         => __( 'Pods', 'pods' ),
					'bidirectional' => true,
				);
			}

			// Post Types for relationships.
			$post_types = get_post_types();
			asort( $post_types );

			$ignore = array( 'attachment', 'revision', 'nav_menu_item' );

			foreach ( $post_types as $post_type => $label ) {
				if ( in_array( $post_type, $ignore, true ) || empty( $post_type ) ) {
					unset( $post_types[ $post_type ] );

					continue;
				} elseif ( 0 === strpos( $post_type, '_pods_' ) && apply_filters( 'pods_pick_ignore_internal', true ) ) {
					unset( $post_types[ $post_type ] );

					continue;
				}

				$post_type = get_post_type_object( $post_type );

				self::$related_objects[ 'post_type-' . $post_type->name ] = array(
					'label'         => $post_type->label . ' (' . $post_type->name . ')',
					'group'         => __( 'Post Types', 'pods' ),
					'bidirectional' => true,
				);
			}

			// Taxonomies for relationships.
			$taxonomies = get_taxonomies();
			asort( $taxonomies );

			$ignore = array( 'nav_menu', 'post_format' );

			foreach ( $taxonomies as $taxonomy => $label ) {
				/**
				 * Prevent ability to extend core Pods content types.
				 *
				 * @param bool $ignore_internal Default is true, when set to false Pods internal content types can not be extended.
				 *
				 * @since 2.3.19
				 */
				$ignore_internal = apply_filters( 'pods_pick_ignore_internal', true );

				if ( in_array( $taxonomy, $ignore, true ) || empty( $taxonomy ) ) {
					unset( $taxonomies[ $taxonomy ] );

					continue;
				} elseif ( 0 === strpos( $taxonomy, '_pods_' ) && $ignore_internal ) {
					unset( $taxonomies[ $taxonomy ] );

					continue;
				}

				$taxonomy = get_taxonomy( $taxonomy );

				self::$related_objects[ 'taxonomy-' . $taxonomy->name ] = array(
					'label'         => $taxonomy->label . ' (' . $taxonomy->name . ')',
					'group'         => __( 'Taxonomies', 'pods' ),
					'bidirectional' => true,
				);
			}//end foreach

			// Other WP Objects for relationships.
			self::$related_objects['user'] = array(
				'label'         => __( 'Users', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'bidirectional' => true,
			);

			self::$related_objects['role'] = array(
				'label'         => __( 'User Roles', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_roles' ),
			);

			self::$related_objects['capability'] = array(
				'label'         => __( 'User Capabilities', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_capabilities' ),
			);

			self::$related_objects['media'] = array(
				'label'         => __( 'Media', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'bidirectional' => true,
			);

			self::$related_objects['comment'] = array(
				'label'         => __( 'Comments', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'bidirectional' => true,
			);

			self::$related_objects['image-size'] = array(
				'label'         => __( 'Image Sizes', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_image_sizes' ),
			);

			self::$related_objects['nav_menu'] = array(
				'label' => __( 'Navigation Menus', 'pods' ),
				'group' => __( 'Other WP Objects', 'pods' ),
			);

			self::$related_objects['post_format'] = array(
				'label' => __( 'Post Formats', 'pods' ),
				'group' => __( 'Other WP Objects', 'pods' ),
			);

			self::$related_objects['post-status'] = array(
				'label'         => __( 'Post Status', 'pods' ),
				'group'         => __( 'Other WP Objects', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_post_stati' ),
			);

			do_action( 'pods_form_ui_field_pick_related_objects_other' );

			self::$related_objects['country'] = array(
				'label'         => __( 'Countries', 'pods' ),
				'group'         => __( 'Predefined Lists', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_countries' ),
			);

			self::$related_objects['us_state'] = array(
				'label'         => __( 'US States', 'pods' ),
				'group'         => __( 'Predefined Lists', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_us_states' ),
			);

			self::$related_objects['ca_province'] = array(
				'label'         => __( 'CA Provinces', 'pods' ),
				'group'         => __( 'Predefined Lists', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_ca_provinces' ),
			);

			self::$related_objects['days_of_week'] = array(
				'label'         => __( 'Calendar - Days of Week', 'pods' ),
				'group'         => __( 'Predefined Lists', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_days_of_week' ),
			);

			self::$related_objects['months_of_year'] = array(
				'label'         => __( 'Calendar - Months of Year', 'pods' ),
				'group'         => __( 'Predefined Lists', 'pods' ),
				'simple'        => true,
				'data_callback' => array( $this, 'data_months_of_year' ),
			);

			do_action( 'pods_form_ui_field_pick_related_objects_predefined' );

			if ( did_action( 'init' ) ) {
				pods_transient_set( 'pods_related_objects', self::$related_objects );
			}
		}//end if

		/**
		 * Allow custom related objects to be defined
		 */
		do_action( 'pods_form_ui_field_pick_related_objects_custom' );

		foreach ( self::$custom_related_objects as $object => $related_object ) {
			if ( ! isset( self::$related_objects[ $object ] ) ) {
				$new_data_loaded = true;

				self::$related_objects[ $object ] = $related_object;
			}
		}

		return $new_data_loaded;

	}
970344
def _write_related_m2m_relations(self, obj, many_to_many_relationships):
        
        for fieldname, related_objs in many_to_many_relationships.items():
            # TODO On PATCH avoid clearing existing relationships not provided?
            setattr(obj, fieldname, related_objs)
1237533
def add_related(self, *objects):
        
        master = None # this will become the common cluster of all related items
        slaves = set([]) # set of clusters that are going to be merged in the master
        solitaire = set([]) # set of new items that are not yet part of a cluster
        for new in objects:
            if isinstance(new, self.cls):
                if master is None:
                    master = new
                else:
                    slaves.add(new)
                for item in new.items:
                    existing = self.lookup.get(item)
                    if existing is not None:
                        slaves.add(existing)
            else:
                cluster = self.lookup.get(new)
                if cluster is None:
                    #print "solitaire", new
                    solitaire.add(new)
                elif master is None:
                    #print "starting master", new
                    master = cluster
                elif master != cluster:
                    #print "in slave", new
                    slaves.add(cluster)
                #else:
                    ##nothing to do
                    #print "new in master", new

        if master is None:
            master = self.cls([])

        for slave in slaves:
            master.update(slave)
        for item in solitaire:
            master.add_item(item)

        for item in master.items:
            self.lookup[item] = master
102240
def add_relationship_methods(self):
        
        Entry = apps.get_model('wagtailrelations', 'Entry')

        @cached_property
        def related(instance):
            return instance.get_related()

        @cached_property
        def related_live(instance):
            return instance.get_related_live()

        @cached_property
        def related_with_scores(instance):
            return instance.get_related_with_scores()

        def get_related(instance):
             entry = Entry.objects.get_for_model(instance)[0]
             return entry.get_related()

        def get_related_live(instance):
             entry = Entry.objects.get_for_model(instance)[0]
             return entry.get_related_live()

        def get_related_with_scores(instance):
            try:
                entry = Entry.objects.get_for_model(instance)[0]
                return entry.get_related_with_scores()
            except IntegrityError:
                return []

        for model in self.applicable_models:
            model.add_to_class(
                'get_related',
                get_related
            )
            model.add_to_class(
                'get_related_live',
                get_related_live
            )
            model.add_to_class(
                'get_related_with_scores',
                get_related_with_scores
            )
            model.add_to_class(
                'related',
                related
            )
            model.add_to_class(
                'related_live',
                related_live
            )
            model.add_to_class(
                'related_with_scores',
                related_with_scores
            )