1+ <?php
2+
3+ namespace App ;
4+
5+ use Carbon \Carbon ;
6+ use Illuminate \Database \Eloquent \Model ;
7+ use Illuminate \Database \Eloquent \Relations \MorphToMany ;
8+ use stdClass ;
9+
10+ /**
11+ * Class Follow.
12+ */
13+ class Follow
14+ {
15+ const RELATION_LIKE = 'like ' ;
16+
17+ const RELATION_FOLLOW = 'follow ' ;
18+
19+ const RELATION_TYPES = [
20+ 'likes ' => 'like ' ,
21+ 'likers ' => 'like ' ,
22+ 'fans ' => 'like ' ,
23+ 'followings ' => 'follow ' ,
24+ 'followers ' => 'follow ' ,
25+ ];
26+
27+ /**
28+ * @param \Illuminate\Database\Eloquent\Model $model
29+ * @param string $relation
30+ * @param array|string|\Illuminate\Database\Eloquent\Model $target
31+ * @param string $class
32+ *
33+ * @return bool
34+ */
35+ public static function isRelationExists (Model $ model , $ relation , $ target , $ class = null )
36+ {
37+ $ target = self ::formatTargets ($ target , $ class ?: User::class);
38+
39+ if ($ model ->relationLoaded ($ relation )) {
40+ return $ model ->{$ relation }->where ($ target ->tableName . '.id ' , head ($ target ->ids ))->isNotEmpty ();
41+ }
42+
43+ return $ model ->{$ relation }($ target ->classname )->where ($ target ->tableName . '.id ' , head ($ target ->ids ))->exists ();
44+ }
45+
46+ /**
47+ * @param \Illuminate\Database\Eloquent\Model $model
48+ * @param string $relation
49+ * @param array|string|\Illuminate\Database\Eloquent\Model $targets
50+ * @param string $class
51+ *
52+ * @throws \Exception
53+ *
54+ * @return array
55+ */
56+ public static function attachRelations (Model $ model , $ relation , $ targets , $ class )
57+ {
58+ $ targets = self ::attachPivotsFromRelation ($ model ->{$ relation }(), $ targets , $ class );
59+
60+ return $ model ->{$ relation }($ targets ->classname )->sync ($ targets ->targets , false );
61+ }
62+
63+ /**
64+ * @param \Illuminate\Database\Eloquent\Model $model
65+ * @param string $relation
66+ * @param array|string|\Illuminate\Database\Eloquent\Model $targets
67+ * @param string $class
68+ *
69+ * @return array
70+ */
71+ public static function detachRelations (Model $ model , $ relation , $ targets , $ class )
72+ {
73+ $ targets = self ::formatTargets ($ targets , $ class );
74+
75+ return $ model ->{$ relation }($ targets ->classname )->detach ($ targets ->ids );
76+ }
77+
78+ /**
79+ * @param \Illuminate\Database\Eloquent\Model $model
80+ * @param string $relation
81+ * @param array|string|\Illuminate\Database\Eloquent\Model $targets
82+ * @param string $class
83+ *
84+ * @throws \Exception
85+ *
86+ * @return array
87+ */
88+ public static function toggleRelations (Model $ model , $ relation , $ targets , $ class )
89+ {
90+ $ targets = self ::attachPivotsFromRelation ($ model ->{$ relation }(), $ targets , $ class );
91+
92+ $ results = $ model ->{$ relation }($ targets ->classname )->toggle ($ targets ->targets );
93+
94+ return $ results ;
95+ }
96+
97+ /**
98+ * @param \Illuminate\Database\Eloquent\Relations\MorphToMany $morph
99+ * @param array|string|\Illuminate\Database\Eloquent\Model $targets
100+ * @param string $class
101+ *
102+ * @throws \Exception
103+ *
104+ * @return \stdClass
105+ */
106+ public static function attachPivotsFromRelation (MorphToMany $ morph , $ targets , $ class )
107+ {
108+ return self ::formatTargets ($ targets , $ class , [
109+ 'relation ' => self ::getRelationTypeFromRelation ($ morph ),
110+ 'created_at ' => Carbon::now ()->format ('Y-m-d H:i:s ' ),
111+ ]);
112+ }
113+
114+ /**
115+ * @param array|string|\Illuminate\Database\Eloquent\Model $targets
116+ * @param string $classname
117+ * @param array $update
118+ *
119+ * @return \stdClass
120+ */
121+ public static function formatTargets ($ targets , $ classname , array $ update = [])
122+ {
123+ $ result = new stdClass ();
124+ $ result ->classname = $ classname ;
125+ $ result ->tableName = null ;
126+
127+ if (!is_array ($ targets )) {
128+ $ targets = [$ targets ];
129+ }
130+
131+ $ result ->ids = array_map (function ($ target ) use ($ result ) {
132+ if ($ target instanceof Model) {
133+ $ result ->classname = get_class ($ target );
134+ $ result ->tableName = $ target ->getTable ();
135+
136+ return $ target ->getKey ();
137+ }
138+
139+ return intval ($ target );
140+ }, $ targets );
141+
142+ $ result ->targets = empty ($ update ) ? $ result ->ids : array_combine ($ result ->ids , array_pad ([], count ($ result ->ids ), $ update ));
143+
144+ return $ result ;
145+ }
146+
147+ /**
148+ * @param \Illuminate\Database\Eloquent\Relations\MorphToMany $relation
149+ *
150+ * @throws \Exception
151+ *
152+ * @return array
153+ */
154+ protected static function getRelationTypeFromRelation (MorphToMany $ relation )
155+ {
156+ if (!\array_key_exists ($ relation ->getRelationName (), self ::RELATION_TYPES )) {
157+ throw new \Exception ('Invalid relation definition. ' );
158+ }
159+
160+ return self ::RELATION_TYPES [$ relation ->getRelationName ()];
161+ }
162+
163+ /**
164+ * @param string $field
165+ *
166+ * @return string
167+ */
168+ protected static function tablePrefixedField ($ field )
169+ {
170+ return \sprintf ('%s.%s ' , config ('follow.followable_table ' ), $ field );
171+ }
172+ }
0 commit comments