Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Latest News Reader Laravel Package

heymowski/latest-news-reader

Laravel package for reading latest news from RSS/Atom feeds using SimplePie. Add feed sources via Artisan command, migrate a DB table, then fetch and store feed items with a command to load all sources.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require heymowski/latest-news-reader
    php artisan migrate
    
    • Verify the news_sources and news_items tables exist in your database.
  2. First Use Case: Adding a News Source

    php artisan LNR-Sources:AddNewsSource
    
    • Follow prompts to input:
      • Name (e.g., "TechCrunch")
      • Feed URL (e.g., https://feeds.feedburner.com/TechCrunch)
      • Update Frequency (e.g., daily or hourly).
    • The package uses SimplePie under the hood, so ensure the feed URL is RSS/Atom-compatible.
  3. Fetching News Items

    php artisan LNR-Items:ReadAll
    
    • Populates the news_items table with parsed feed items (title, description, link, published date).
    • Check database/news_items for results.
  4. Displaying News in a View Inject the service into a controller:

    use Heymowski\LatestNewsReader\Facades\NewsReader;
    
    public function showNews()
    {
        $items = NewsReader::getLatestItems(5); // Fetch 5 latest items
        return view('news.index', compact('items'));
    }
    
    • Blade template example:
      @foreach($items as $item)
          <article>
              <h3><a href="{{ $item->link }}">{{ $item->title }}</a></h3>
              <p>{{ Str::limit($item->description, 100) }}</p>
              <small>{{ $item->published_at->format('M d, Y') }}</small>
          </article>
      @endforeach
      

Implementation Patterns

Core Workflows

  1. Scheduled Updates Use Laravel’s scheduler to auto-fetch feeds (e.g., daily):

    // app/Console/Kernel.php
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('LNR-Items:ReadAll')->daily();
    }
    
    • Tip: Add a last_updated_at column to news_sources to avoid redundant fetches.
  2. Dynamic Source Management

    • Add/Edit Sources Programmatically:
      use Heymowski\LatestNewsReader\Models\NewsSource;
      
      $source = NewsSource::create([
          'name' => 'BBC News',
          'feed_url' => 'http://feeds.bbci.co.uk/news/rss.xml',
          'frequency' => 'hourly',
      ]);
      
    • Trigger Updates:
      $source->updateFeed(); // Manually fetch items for a specific source
      
  3. Filtering and Querying

    • Fetch items by source:
      $techNews = NewsReader::getItemsBySource('TechCrunch', 10);
      
    • Filter by date range:
      $recentItems = NewsReader::getItems()->where('published_at', '>', now()->subDays(7))->get();
      
  4. Caching for Performance

    • Cache fetched items for 1 hour:
      $items = Cache::remember('latest_news_items', now()->addHours(1), function () {
          return NewsReader::getLatestItems(10);
      });
      

Integration Tips

  • Service Provider Binding: Extend the package’s NewsReader facade to add custom logic:

    // app/Providers/AppServiceProvider.php
    public function boot()
    {
        \Heymowski\LatestNewsReader\Facades\NewsReader::extend(function ($app) {
            return new class($app['news-reader']) {
                public function getTrendingItems($limit = 5) {
                    // Custom logic (e.g., filter by engagement metrics)
                }
            };
        });
    }
    
  • Event Listeners: Listen for feed updates to trigger notifications:

    // app/Providers/EventServiceProvider.php
    protected $listen = [
        \Heymowski\LatestNewsReader\Events\FeedUpdated::class => [
            \App\Listeners\SendNewsletter::class,
        ],
    ];
    
  • API Endpoints: Expose news items via Laravel API:

    Route::get('/api/news', function () {
        return NewsReader::getLatestItems(20);
    });
    

Gotchas and Tips

Pitfalls

  1. Feed Parsing Errors

    • Issue: SimplePie may fail on malformed feeds (e.g., missing <title> tags).
    • Fix: Wrap NewsReader::getLatestItems() in a try-catch:
      try {
          $items = NewsReader::getLatestItems();
      } catch (\Exception $e) {
          Log::error("Feed parse error: " . $e->getMessage());
          return back()->with('error', 'Failed to fetch news.');
      }
      
    • Debug: Check storage/logs/laravel.log for SimplePie errors.
  2. Duplicate Items

    • Issue: The same feed item may be re-fetched if not deduplicated.
    • Fix: Add a guid column to news_items and use Laravel’s unique() rule:
      // app/Models/NewsItem.php
      protected $fillable = ['title', 'description', 'link', 'published_at', 'guid'];
      protected $unique = ['guid'];
      
  3. Rate Limiting

    • Issue: Aggressive scraping may trigger rate limits (e.g., 429 Too Many Requests).
    • Fix: Implement exponential backoff in the ReadAll command:
      // app/Console/Commands/ReadAll.php
      public function handle()
      {
          $attempts = 0;
          while ($attempts < 3) {
              try {
                  $this->fetchFeeds();
                  break;
              } catch (\GuzzleHttp\Exception\RequestException $e) {
                  if ($e->getCode() === 429) {
                      sleep(2 ** $attempts); // Exponential backoff
                      $attempts++;
                  } else {
                      throw $e;
                  }
              }
          }
      }
      
  4. Timezone Mismatches

    • Issue: published_at may not align with your app’s timezone.
    • Fix: Normalize dates in the NewsItem model:
      // app/Models/NewsItem.php
      protected $dates = ['published_at'];
      protected $appends = ['formatted_date'];
      
      public function getFormattedDateAttribute()
      {
          return $this->published_at->setTimezone('America/New_York')->format('M d, Y H:i');
      }
      

Debugging Tips

  • Inspect Raw Feed Data: Dump the parsed feed object before saving:

    $feed = NewsReader::parseFeed($source->feed_url);
    dd($feed->get_items()); // Debug SimplePie items
    
  • Artisan Debugging: Use Tinker to test queries:

    php artisan tinker
    >>> \Heymowski\LatestNewsReader\Models\NewsSource::all();
    >>> \Heymowski\LatestNewsReader\Models\NewsItem::latest()->take(5)->get();
    

Extension Points

  1. Custom Fields Extend the news_items table and model:

    // Migration
    Schema::table('news_items', function (Blueprint $table) {
        $table->string('author')->nullable();
        $table->string('image_url')->nullable();
    });
    
    // Model
    public $fillable = ['title', 'description', 'link', 'published_at', 'guid', 'author', 'image_url'];
    
  2. Override Parsing Logic Bind a custom parser to the news-reader service:

    // config/news-reader.php
    'parser' => \App\Services\CustomFeedParser::class,
    

    Implement Heymowski\LatestNewsReader\Contracts\FeedParser.

  3. Webhooks for Updates Trigger external APIs when feeds update:

    // app/Providers/EventServiceProvider.php
    protected $listen = [
        \Heymowski\LatestNewsReader\Events\FeedUpdated::class => [
            \App\Listeners\DispatchWebhook::class,
        ],
    ];
    
  4. Localization Handle non-English feeds by adding a locale column and translating titles/descriptions:

    use LaravelLocalization;
    
    $translatedTitle = LaravelLocalization::trans($item->title, [], 'en');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope