title: Building a deep Nested array of objects in PHP using Recursion
body: <p>Basically, this is what I want to achieve</p>
  <pre><code>Jason
     -&gt;Ronda
            -&gt;Cat
                 -&gt;Abraham
                 -&gt;Jacob
       
    -&gt;Joseph
            -&gt;Brock
            -&gt;Dustin 
  </code></pre>
  <p>In JSON Format, this is what I would like to achieve</p>
  <pre><code>{
      id: 1,
      username: Jason,
      children: [
          {
              id:2,
              username:Ronda,
              children: [
                  {
                      id:4,
                      name: Cat,
                      children:[
                          {
                              id:8,
                              username:Abraham,
                              children:[]
                          },
                          {
                              id:9,
                              username:Jacob,
                              children:[]
                          }
                      ]
                  },
                  {
                      id:5,
                      username:Connor,
                      children:[]
                  }
              ]
          },
          {
              id:3,
              username:Joseph,
              children: [
                  {
                      id:6,
                      username:Brock,
                      children: []
                  },
                                  {
                      id:7,
                      username:Dustin,
                      children: []
                  },
              ]
          }    
      ]
  }
  </code></pre>
  <p>I have 2 tables in my database</p>
  <pre><code>Users
  id username  parent
  1  Jason      null
  2  Ronda       1
  3  Joseph      1
  4  Cat         2
  5  Connor      2
  6  Brock       3
  7  Dustin      3
  8  Abraham     4
  9  Jacob       4
  
  UserLevels
  id  upline downline level
  1    1      2          1
  2    1      3          1
  3    1      4          2
  4    1      5          2
  5    1      6          2
  6    1      7          2
  7    1      8          3
  8    1      9          3
  9    2      4          1
  10   2      5          1
  11   2      8          2
  12   2      9          2
  13   3      6          1
  14   3      7          1
  </code></pre>
  <p>Basically the user levels table is showing how deep or how each person is related to. For an example,Jacob is the great grandchild of Jason. Hence the userlevels id 8 represents their relationship. Jason is the upline which is user id 1, Jacob is the downline which is user id 9 , and it is 3 levels deep.</p>
  <p>This is my code.</p>
  <p>ListController.php (Controller)</p>
  <pre><code>use App\Http\Controllers\Controller;
  use Illuminate\Http\Request;
  use Illuminate\Support\Facades\Schema;
  use Illuminate\Support\Collection;
  use Inertia\Inertia;
  use Carbon\Carbon;
  
  
  use App\Models\User;
  use App\Models\UserLevel;
  use Auth;
  
  class ListController extends Controller {
      protected function getDownline($upline) {
          return UserLevel::where([
              'upline' =&gt; $upline,
              'level' =&gt; 1
          ])-&gt;get();
      }
  
      protected function getUserName($id) {
          return User::findOrFail($id)-&gt;username;
      }
      
      //Recursion here
      public function getHierachyDataHelper($downline,$currentUserId) {
          $result = collect([
              'id' =&gt;$currentUserId,
              'username' =&gt; $this-&gt;getUserName($currentUserId),
              'children' =&gt; collect()
          ]);
          foreach ($downline as $key =&gt; $child) {
              # code...
              $result['children']-&gt;push(collect([
                  'id' =&gt;$child['downline'],
                  'username' =&gt; $this-&gt;getUserName($child['downline']),
                  'children' =&gt; collect()
              ]));
              $children = $this-&gt;getDownline($child['downline']);
              if ($children-&gt;count() &gt; 0 ) {
                  # code...
                  $this-&gt;getHierachyDataHelper($children , $child['downline']);
              }
          }
          return response()-&gt;json([
              'data' =&gt;$result
          ]);
          
      }
      
      public function getHierachyData() {
          $currentUser = Auth::user();
          $downline = $this-&gt;getDownline($currentUser-&gt;id);
          return $this-&gt;getHierachyDataHelper($downline,$currentUser-&gt;id);
      }
  
  }
  </code></pre>
  <p>UserLevel.php (model)</p>
  <pre><code>&lt;?php
  
  namespace App\Models;
  
  use App\Models\User;
  
  use Illuminate\Database\Eloquent\Factories\HasFactory;
  use Illuminate\Database\Eloquent\Model;
  
  class UserLevel extends Model
  {
      use HasFactory;
      protected $table = &quot;user_levels&quot;;
  
      protected $fillable = [
          'upline',
          'downline',
          'level',
      ];
  
  
      public function uplineUser()
      {
          return $this-&gt;belongsTo(User::class, 'upline');
      }
  
  
      public function downlineUser()
      {
          return $this-&gt;belongsTo(User::class, 'downline');
      }
  }
  </code></pre>
  <p>User.php(model)</p>
  <pre><code>&lt;?php
  
  namespace App\Models;
  
  use Illuminate\Contracts\Auth\MustVerifyEmail;
  use Illuminate\Database\Eloquent\Factories\HasFactory;
  use Illuminate\Foundation\Auth\User as Authenticatable;
  use Illuminate\Notifications\Notifiable;
  use Laravel\Sanctum\HasApiTokens;
  
  class User extends Authenticatable
  {
      use HasApiTokens, HasFactory, Notifiable;
  
      /**
       * The attributes that are mass assignable.
       *
       * @var array&lt;int, string&gt;
       */
      protected $fillable = [
          'name',
          'email',
          'password',
      ];
  
      /**
       * The attributes that should be hidden for serialization.
       *
       * @var array&lt;int, string&gt;
       */
      protected $hidden = [
          'password',
          'remember_token',
      ];
  
      /**
       * The attributes that should be cast.
       *
       * @var array&lt;string, string&gt;
       */
      protected $casts = [
          'email_verified_at' =&gt; 'datetime',
      ];
  }
  </code></pre>
  <p>Appreciate any help given, Thank you very much :)</p>