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

Feed Io Laravel Package

debril/feed-io

PHP library to read and write RSS, Atom, and JSONFeed. Supports feed autodiscovery, enclosures, logos, content filtering, and DateTime conversion. Includes CLI tools, PSR-7 responses with cache headers, PSR-3 logging, and PSR-18 HTTP clients.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation:

    composer require php-feed-io/feed-io
    

    Ensure your project meets PHP 8.1+ requirements (or 7.1+ for v4.x).

  2. Basic Feed Consumption:

    use FeedIo\FeedIo;
    use FeedIo\Adapter\Guzzle\Client;
    use GuzzleHttp\Client as GuzzleClient;
    
    $client = new Client(new GuzzleClient());
    $feedIo = new FeedIo($client, new \Psr\Log\NullLogger());
    
    $result = $feedIo->read('https://example.com/feed.atom');
    echo $result->getFeed()->getTitle();
    
  3. First Practical Use Case: Fetch and display the 5 newest items from a feed:

    foreach ($result->getFeed() as $index => $item) {
        if ($index >= 5) break;
        echo $item->getTitle() . "\n";
    }
    

Where to Look First

  • README: Official documentation with examples.
  • API Docs: Class references for FeedIo, Feed, Item, etc.
  • CLI Usage: Quick testing via ./vendor/bin/feedio read <url>.
  • Filtering Guide: How to use Since, Chain, and custom filters.

Implementation Patterns

Core Workflows

1. Consuming Feeds with Filters

  • Pattern: Use getItemsSince() or custom filters to avoid reprocessing old items.
  • Example:
    $modifiedSince = new \DateTime('2023-01-01');
    $result = $feedIo->read('https://blog.example.com/feed', null, $modifiedSince);
    
    foreach ($result->getItemsSince() as $item) {
        // Process only new items
        $this->storeInDatabase($item);
    }
    

2. Generating Feeds for APIs

  • Pattern: Convert Laravel models/collections to FeedIo\Feed and return as PSR-7 response.
  • Example:
    $feed = new \FeedIo\Feed();
    $feed->setTitle('My Blog Updates');
    $feed->setLink('https://blog.example.com');
    
    foreach ($posts as $post) {
        $item = $feed->newItem();
        $item->setTitle($post->title)
             ->setLink($post->url)
             ->setDate($post->published_at);
        $feed->add($item);
    }
    
    return $feedIo->getPsrResponse($feed, 'atom');
    

3. Auto-Discovering Feeds

  • Pattern: Scrape HTML headers for <link> tags or use the CLI.
  • Example:
    $discoveredFeeds = $feedIo->discover('https://example.com');
    foreach ($discoveredFeeds as $feedUrl) {
        $this->subscribeToFeed($feedUrl);
    }
    

4. Handling Media (Podcasts/Videos)

  • Pattern: Attach enclosures to feed items for audio/video content.
  • Example:
    $item = $feed->newItem();
    $media = new \FeedIo\Feed\Item\Media();
    $media->setUrl('https://example.com/podcast.mp3')
          ->setType('audio/mpeg')
          ->setLength('1200'); // Duration in seconds
    $item->addMedia($media);
    

5. Optimizing Updates

  • Pattern: Use getNextUpdate() to schedule feed checks efficiently.
  • Example:
    $nextUpdate = $result->getNextUpdate();
    $this->scheduleCronJob($nextUpdate->format('Y-m-d H:i:s'));
    

Integration Tips

  • Laravel-Specific:

    • Use Http::client() for the HTTP adapter:
      $client = new \FeedIo\Adapter\Http\Client(Http::client());
      
    • Store feed results in the cache with Cache::remember() to avoid redundant parsing.
    • Log feed errors with Laravel’s logging system:
      $logger = \Log::channel('feed');
      $feedIo = new FeedIo($client, $logger);
      
  • Queueing Feed Processing:

    • Dispatch jobs for feed updates to avoid blocking requests:
      FeedUpdateJob::dispatch($feedUrl, $modifiedSince)->onQueue('feeds');
      
  • Testing:

    • Mock the HTTP client and logger for unit tests:
      $mockClient = Mockery::mock(\FeedIo\Adapter\ClientInterface::class);
      $mockClient->shouldReceive('get')->andReturn($response);
      $feedIo = new FeedIo($mockClient, $logger);
      

Gotchas and Tips

Pitfalls

  1. Timezone Handling:

    • Issue: Feeds may omit timezones, causing incorrect date comparisons.
    • Fix: Set a default timezone for the DateTimeBuilder:
      $feedIo->getDateTimeBuilder()->setFeedTimezone(new \DateTimeZone('UTC'));
      // Don't forget to reset after use!
      $feedIo->getDateTimeBuilder()->resetFeedTimezone();
      
  2. Relative URLs:

    • Issue: Some feeds use relative links (e.g., /images/logo.png). Newer versions (v5.3.2+) support this, but older versions may fail.
    • Fix: Upgrade to v5.3.2+ or prepend the base URL:
      $item->setLink('https://example.com' . $relativePath);
      
  3. HTTP Client Quirks:

    • Issue: Some PSR-18 clients (e.g., custom implementations) may not handle redirects or headers correctly.
    • Fix: Use a well-tested adapter like Symfony\Component\HttpClient\HttplugClient or Guzzle.
  4. Memory Usage:

    • Issue: Large feeds (e.g., 10,000+ items) may consume significant memory.
    • Fix: Stream items or use chunked processing:
      $items = iterator_to_array($result->getFeed(), false); // Lazy loading
      
  5. Feed Format Detection:

    • Issue: Auto-detection may fail for malformed feeds.
    • Fix: Explicitly specify the format:
      $result = $feedIo->read('https://example.com/feed', 'atom');
      
  6. Caching Headers:

    • Issue: getPsrResponse() may not set optimal cache headers for dynamic feeds.
    • Fix: Manually configure headers:
      $response = $feedIo->getPsrResponse($feed, 'atom');
      $response = $response->withAddedHeader('Cache-Control', 'max-age=3600');
      

Debugging Tips

  • Enable Logging:

    • Use Monolog or Laravel’s logger to debug HTTP requests/responses:
      $logger = \Log::channel('feed');
      $feedIo = new FeedIo($client, $logger);
      
    • Check logs for errors like 404 Not Found or malformed XML/JSON.
  • Validate Feeds:

    • Use online validators (e.g., FeedValidator.org) to check feed syntax before processing.
  • Inspect Raw Responses:

    • Access the underlying HTTP response for debugging:
      $result = $feedIo->read($url);
      $rawResponse = $result->getResponse(); // PSR-7 ResponseInterface
      

Extension Points

  1. Custom Filters:

    • Implement \FeedIo\Filter\FilterInterface to add logic (e.g., database sync, content moderation):
      class DatabaseFilter implements FilterInterface {
          public function filter(Feed $feed, array $items) {
              return array_filter($items, fn($item) => $this->isValid($item));
          }
      }
      
  2. Custom Feed Formats:

    • Extend \FeedIo\Feed or \FeedIo\Feed\Item to support non-standard elements:
      $feed->set('custom,namespace', 'value');
      
  3. HTTP Client Middleware:

    • Add interceptors (e.g., authentication, retries) via PSR-18 middleware:
      $client = new \FeedIo\Adapter\Http\Client(
          Http::withOptions(['timeout' => 10])
      );
      
  4. DateTime Handling:

    • Override DateTimeBuilder to customize date parsing:
      $feed
      
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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