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

Speedy Pickup Point Bundle Laravel Package

answear/speedy-pickup-point-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require answear/speedy-pickup-point-bundle
    

    The bundle auto-registers in config/bundles.php via Symfony Flex.

  2. Configuration Add credentials to config/packages/answear.yaml:

    answear_speedy:
        username: 'your_speedy_username'
        password: 'your_speedy_password'
        language: 'BG'  # Bulgarian (required)
        clientSystemId: 12345  # Your Speedy client ID
    
  3. First Use Case: Find Nearest Office

    use Answear\SpeedyBundle\Command\FindOffice;
    use Answear\SpeedyBundle\Request\FindOfficeRequest;
    
    $findOffice = new FindOffice(); // Autowired via DI
    $request = new FindOfficeRequest('1000', 'Sofia'); // Postcode, city
    $response = $findOffice->findOffice($request);
    

Key Classes to Explore

  • Commands: FindOffice, GetAllSites, GetAllPostcodes
  • Requests: FindOfficeRequest, GetAllSitesRequest, GetAllPostcodesRequest
  • Responses: Check src/Response/ for parsed API data (e.g., OfficeResponse)

Implementation Patterns

Common Workflows

1. Office Lookup

// Find office by postcode/city
$request = new FindOfficeRequest('1303', 'Sofia');
$response = $findOffice->findOffice($request);

// Access office data
$office = $response->getOffice();
$schedule = $office->getOpeningSchedule(); // OpeningHours[]

2. Bulk Data Fetching

// Get all Speedy sites (cached by default)
$allSites = $getAllSites->getAllSites(new GetAllSitesRequest());

// Get all supported postcodes
$postcodes = $getAllPostcodes->getAllPostcodes(new GetAllPostcodesRequest());

3. Integration with Laravel Controllers

use Answear\SpeedyBundle\Command\FindOffice;

class PickupController extends Controller
{
    public function __construct(
        private FindOffice $findOffice
    ) {}

    public function search(Request $request)
    {
        $requestData = new FindOfficeRequest(
            $request->postcode,
            $request->city
        );
        $office = $this->findOffice->findOffice($requestData);
        return view('pickup', ['office' => $office->getOffice()]);
    }
}

4. Service Layer Abstraction

Create a dedicated service to encapsulate Speedy logic:

namespace App\Services;

use Answear\SpeedyBundle\Command\FindOffice;
use Answear\SpeedyBundle\Request\FindOfficeRequest;

class SpeedyService
{
    public function __construct(private FindOffice $findOffice) {}

    public function findNearestOffice(string $postcode, string $city)
    {
        $request = new FindOfficeRequest($postcode, $city);
        $response = $this->findOffice->findOffice($request);
        return $response->getOffice();
    }
}

Best Practices

  • Dependency Injection: Always inject commands via constructor (Laravel’s service container handles this).
  • Error Handling: Wrap calls in try-catch for Answear\SpeedyBundle\Exception\SpeedyException.
  • Caching: Responses are cached by default (TTL configurable via answear_speedy.cache_ttl in config).
  • Logging: Enable debug logging for API issues:
    answear_speedy:
        debug: true
    

Gotchas and Tips

Pitfalls

  1. Authentication Failures

    • Symptom: 401 Unauthorized or empty responses.
    • Fix: Verify username/password in config and check Speedy API credentials.
    • Debug: Enable debug: true in config to log raw API responses.
  2. Postcode/City Validation

    • Speedy’s API is Bulgaria-only (language: 'BG'). Non-BG postcodes/cities return null.
    • Tip: Pre-validate inputs against GetAllPostcodesRequest results.
  3. Rate Limiting

    • Speedy’s API has undocumented limits. Avoid rapid successive calls.
    • Workaround: Implement a simple rate limiter in your service layer.
  4. Breaking Changes

    • Symfony 5.4+ only: Upgrading from older Symfony versions may require dependency updates.
    • Guzzle 7: If using Symfony 6+, ensure guzzlehttp/guzzle:^7.0 is installed.

Debugging Tips

  • Raw API Responses:
    $response = $findOffice->findOffice($request);
    if ($response->isDebugEnabled()) {
        \Log::debug('Raw API Response:', [$response->getRawResponse()]);
    }
    
  • Common HTTP Errors:
    • 400: Invalid request (check postcode/city format).
    • 500: Speedy server error (contact support).
    • 429: Too many requests (add delays).

Extension Points

  1. Custom Requests Extend Answear\SpeedyBundle\Request\AbstractRequest to add new endpoints:

    namespace App\Speedy;
    
    use Answear\SpeedyBundle\Request\AbstractRequest;
    
    class CustomRequest extends AbstractRequest
    {
        protected string $endpoint = 'custom/endpoint';
        protected array $queryParams = ['param' => 'value'];
    }
    
  2. Response Parsing Override Answear\SpeedyBundle\Response\AbstractResponse to handle custom API fields:

    namespace App\Speedy\Response;
    
    use Answear\SpeedyBundle\Response\AbstractResponse;
    
    class CustomResponse extends AbstractResponse
    {
        public function getCustomField(): string
        {
            return $this->data['custom_field'] ?? null;
        }
    }
    
  3. Configuration Overrides Override bundle config via config/packages/answear.yaml:

    answear_speedy:
        timeout: 30       # Default: 10s (from Guzzle)
        cache_ttl: 3600   # Cache responses for 1 hour
    

Pro Tips

  • Batch Processing: Use GetAllSitesRequest to preload all offices for offline use (e.g., in a PickupPoint table).
  • Geocoding: Combine with a geocoding service (e.g., Google Maps) to resolve fuzzy city names.
  • Fallback Logic: Cache failed requests to avoid repeated API calls for invalid inputs.
  • Testing: Mock FindOffice in unit tests:
    $this->mock(FindOffice::class)
         ->shouldReceive('findOffice')
         ->andReturn(new OfficeResponse($mockOfficeData));
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui