Contact
Let's work together
European B2B Search Engine for Promotional Products (European Sourcing)

European B2B Search Engine for Promotional Products (European Sourcing)

B2B search engine acting as an online tradeshow for European promotional products resellers - a precursor to today's marketplaces.

2010 - 2016
~6 years
Software Engineer then Senior Software Engineer
PHP 5.xSymfony 2/3MySQLElasticsearchAngularJSDoctrine ORMZend FrameworkMemcacheRabbitMQApacheProxmox VE

Lines of Code

~9.2M

PHP, JS, Twig, CSS, HTML

Database Tables

97

MySQL (master-slave)

Sub-Applications

15+

Microservices ecosystem

Languages Supported

7

FR, EN, DE, ES, IT, NL, PT

Dedicated Servers

9

OVH Proxmox VE

Supplier Connectors

26+

Automated data import

Versioning Entries

1,234

836 Git + 398 SVN

Reseller Websites

~160

MyEasyWeb hosted CMS

Presentation & Project Definition

Fifteen interconnected sub-applications, four search-engine generations, 8 years of development

European Sourcing is a B2B search engine for promotional products acting as a permanent online tradeshow at European scale - a precursor to what we call marketplaces today, aimed at all European promotional products resellers. The project constitutes a complete application ecosystem composed of fifteen interconnected sub-applications, developed over more than 6 years (2010-2017).

The platform connects three types of actors in the promotional products market:

  • Suppliers (manufacturers/wholesalers) who list their product catalogs → B2B
  • Resellers/Distributors (communication agencies) who search products for their clients → B2B
  • Visitors who browse the online catalog on reseller sites (end clients) → B2C

The system functions as a permanent professional online tradeshow, offering suppliers a multi-channel showcase (online catalog, newsletters, advertising banners, annual guidebook, Google Ads) and resellers a multilingual product search engine covering 7 European languages.

Business Domain

B2B communication through promotional objects - connecting European suppliers, resellers, and agencies in the promotional products industry.

Target Users

B2B professionals across Europe - communication agencies, distributors and examples of integrated European suppliers (Midocean, PF Concept, BIC, Paul Stricker, SOL'S, TopTex, Topico, Inspirion, Makito, Xindao, Clipper, Cybernecard, Pixika, Delta, Passot, Lm, Boomerang, Axpol, Goya, GetImpressed, Giving, Lensen Toppoint, Cottel, Eljte, Frezal, Imbretex).

Functional Scope
Multilingual Product Catalog (7 languages)
Full-Text Search (Elasticsearch)
Supplier/Reseller Back-Office
Automated Supplier Data Import (26+ connectors)
REST API with WSSE Authentication
Centralized Translation System
Online Payment (Sogenactif)
Reseller Mini-Sites CMS (MyEasyWeb)
Mobile Applications (PhoneGap/Cordova)
Consultation Statistics (views, searches, clicks)
Data Export (CSV + product images)
SEO / Marketing Back-Office

Objectives, Context, Stakes & Risks

Digitalizing the European promotional products market

Objectives
  • Position the platform as the European reference for online B2B promotional products sourcing, replacing paper catalogs and physical tradeshows
  • Build a multilingual product catalog aggregating several million products and variants from dozens of suppliers
  • Provide resellers with an advanced search engine with filters by category, brand, price, attributes, marking
  • Automate the import of supplier data feeds (prices, stocks, docs, descriptions) from 26+ suppliers
  • Offer resellers a turnkey mini-site e-commerce solution (MyEasyWeb) with their own branded storefront connected to the central catalog
  • Generate detailed consultation statistics for suppliers (product views, searches, clicks)
Context

The initial project (v1/v2) was developed by SQLI, a French IT services company, with a custom PHP framework and Smarty templates. The legacy code contained 398 SVN revisions covering 2010-2013.

When I joined SQLI, 5 full-time PHP developers were dedicated to the project. Over time, I took on a growing share of the technical scope, eventually handling the entire perimeter on my own - a role that naturally evolved with my expertise and the autonomy that came with the PME environment. After covering the full perimeter solo for a while, I asked for reinforcement and obtained the hiring of a second developer.

From 2014-2016, our new Medialeads team undertook a complete rewrite of the platform, progressively migrating from the custom framework to Symfony 2/3 while maintaining the public site on a lighter custom MVC framework.

The platform was multilingual (7 languages), multi-country, with high product data volumes, and the need to maintain compatibility with existing supplier data feeds - all hosted on fully self-managed OVH dedicated servers: we handled absolutely everything ourselves, from system configuration to deployments.

Stakes

Business Model

Revenue from supplier subscriptions (240-288 EUR/year) and advertising services (banners, newsletters, guidebook, Google Ads, media planning).

Strategic Position

European Sourcing positioned itself as the go-to reference for online promotional product sourcing in Europe - a precursor to today's B2B marketplaces, replacing traditional paper catalogs and physical tradeshows.

Brand Ecosystem

The company also operated TendanceObjet.com, Kadobjet.fr, FranceObjet.com, Omyague.com, GourmetOnline.pro, Recherche-Publicitaire.com, GraphicSourcing.com, CPrint-Sourcing.com, WineSpiritSourcing.com, Tradexpo-Online.fr - each targeting a specific market segment.

Identified Risks

Technical Debt

Progressive migration from a custom framework to Symfony, coexistence of two architectures (SVN legacy + Git modern), MD5 password hashing with a single iteration and no salt - consistent with the state of the art of PHP security practices during the 2008-2014 decade, before bcrypt became the default standard.

Integration Complexity

Supplier data feeds were heterogeneous (CSV, XML, API), requiring a specific adapter per supplier maintained in flux.europeansourcing.com.

Infrastructure Dependency

9 dedicated OVH servers with Proxmox virtualization, MySQL master/slave replication, manual deployments via svn up - reflecting the technical constraints of the era, before the democratization of Docker and modern CI/CD pipelines.

Bus Factor

Only 3 main developers for the entire ecosystem of 38 sub-projects and 9 servers.

The Steps - What I Did

From SQLI monolith to distributed microservices architecture

Phase 1
SQLI Development & SVN Legacy (2008-2013)
2008 - 2013
  • Managed the legacy codebase inherited from SQLI - a PHP monolith with Smarty templates, under SVN versioning (398 revisions)
  • Maintained and extended the extranet for suppliers and resellers (product CRUD, image management, pricing, attributes, markings)
  • Handled deployment operations on dedicated servers and coordinated with SQLI documentation (47+ specification documents)
  • Developed data correction scripts to fix quality issues (missing parent categories, incorrect colors, broken docs)
Phase 2
Internal Takeover & Microservices (2014-2016)
Jan 2016 - Dec 2016
  • Led the migration from SVN to GitHub - 13 repositories created in January 2016, organization medialeads with 8 members and 20+ private repos
  • Rewrote the extranet (177 commits) on a custom PHP MVC framework with direct MySQL database access
  • Developed the REST API (api.europeansourcing.com) on Symfony 2.4 with Propel ORM and WSSE authentication
  • Built automated supplier data connectors on flux.europeansourcing.com (Pixika, Makito, Midocean, BIC, Paul Stricker, TopTex, Cybernecard)
  • Implemented Elasticsearch full-text search with dedicated multilingual indexes
  • Created the centralized translation system (translate.europeansourcing.com) on Symfony 3.0
Phase 3
Architectural Modernization (2016-2017)
Mar 2016 - Nov 2016
  • Initiated the architectural rewrite with shared Symfony bundles (ESCoreBundle: 143 commits, ESSourcingBundle: 15 commits)
  • Designed Doctrine behaviors: Sluggable, Sortable, Timestampable, Translatable, Blameable, Toggleable, Visible, Overloadable, Tree
  • Implemented asynchronous processing with RabbitMQ for data import and visibility computations
  • Set up infrastructure provisioning with Chef for the extranet_rebirth project
Project Timeline
European Sourcing - 2008-2017
Supplier Data Import Flow

The Actors - Interactions

Collaborating within a small but highly productive team

Development Team

3 to 5 active developers depending on the period, with clearly divided responsibilities:

José DA COSTA

Lead Developer - 35.3% of total versioning (225 Git + 116 SVN). Dominant on extranet (177 commits), flux (15), SVN legacy management.

Thomas C.

Senior Developer - 36.9% (355 Git + 1 SVN). Dominant on ESCoreBundle (113), translate (88), supplierbo (19).

wamania

Developer - 24.2% (226 Git + 8 SVN). Dominant on europeansourcing.com (166 commits), extranet (49).

IronXtreme

Developer - 3.0% (29 Git commits on ESCoreBundle).

Contribution Distribution (Git + SVN)
External Stakeholders

SQLI

IT services company that developed v1/v2/v3 (specifications, initial development)

Dolead

Google AdWords management agency

Universem

SEO agency (audits for TendanceObjet and Kadobjet)

OVH

Hosting provider (9 dedicated servers)

The Results

Measurable impact for the business and for my career

For Me
  • Massive data management & SQL optimization: mastery of SQL normal forms (1NF, 2NF, 3NF, BCNF), all join types (INNER/LEFT/RIGHT/CROSS/SELF), advanced indexing (B-tree, composite, covering indexes), constant `EXPLAIN ANALYZE` plan analysis, MySQL master-slave replication and Memcache caching. Ran nightly batches of several hours to recompute stock levels, prices and promotions across the whole catalog - at that scale a missing index could turn a 50 ms query into a 30-second timeout, so every millisecond saved per query compounded over millions of executions.
  • Search engines & indexing: hands-on progression across four generations of search engines - (1) MySQL LIKE / FULLTEXT (MyISAM/InnoDB), (2) PostgreSQL full-text search with `tsvector`/`tsquery`, GIN indexes and `to_tsvector`/`ts_rank` functions, (3) Apache Solr indexing hundreds of thousands of products with advanced faceting (categories, colors, prices, suppliers), spell-checking and custom relevance scoring, (4) Elasticsearch with inverted indexes, multilingual analyzers (stemming, tokenization, normalization), TF-IDF scoring, aggregations and facets. Learned the deep differences between a relational engine and a dedicated search engine.
  • Complex algorithms & business rules: design and implementation of numerous complex algorithms and intricate business rules - for example computing every possible combination of price, product variants and availability (Cartesian product / combinatorial explosion generating thousands of combinations per product across sizes, colors, quantities, marking types, marking zones and finishes). Mastery of dynamic pricing rule modeling and business decision engines.
  • Mastered Symfony 2/3 ecosystem at production scale (Propel, Doctrine, bundles, services, security, WSSE)
  • Developed strong skills in legacy code migration - transitioning from SVN monolith to Git-based microservices without downtime
  • Built domain knowledge in B2B promotional products market, data feed automation, and multi-country e-commerce
  • Learned to coordinate within a small team where each developer owns significant portions of the codebase
For the Company

Functional Coverage

Complete B2B sourcing lifecycle handled within a single ecosystem - from supplier catalog upload to reseller storefront, with no manual handover between services

Catalog Volume

Indexed the largest European database of promotional products - several million products and variants aggregated from 26+ supplier feeds, stored across 97 MySQL tables with master-slave replication

Multilingual Reach

7 European languages with dedicated Elasticsearch indexes and centralized translation management

Geographic Coverage

Localized sub-domains covering key European markets: UK, Iberia, Italy, Germany, plus a dedicated Textile vertical

Automation Scale

26+ automated supplier connectors handling heterogeneous formats (CSV, XML, API) from major European brands

Reseller Network

~160 hosted reseller mini-sites on the MyEasyWeb CMS platform

Brand Ecosystem

11+ domain brands operated: europeansourcing.com, tendanceobjet.com, kadobjet.fr, franceobjet.com, omyague.com, gourmetonline.pro, recherche-publicitaire.com, graphicsourcing.com, cprint-sourcing.com, winespiritsourcing.com, tradexpo-online.fr

Key features delivered

Multilingual product catalog with dedicated Elasticsearch indexes and custom relevance scoring
REST API with WSSE stateless authentication (nonce + timestamp + digest)
Automated supplier data import connectors handling heterogeneous CSV / XML / API feeds
Supplier/reseller back-office with complete product management
SPA supplier dashboard (AngularJS 1.2 + CoffeeScript + Grunt + Bower)
Reseller mini-sites CMS (MyEasyWeb) with branded storefronts connected to the central catalog
Online payment integration (Sogenactif, Société Générale)
SEO / marketing back-office (Zend Framework + ExtJS + web crawler)
Hybrid mobile applications (jQuery Mobile + PhoneGap/Cordova)
Microservices Ecosystem
Technology Distribution
Codebase Scale
7,514PHP files
4,505JS files
909Controllers
2,222Views / templates
87Cron jobs
1,506i18n files
611Test files

The Aftermath

What happened after I left the project

I left the project in November 2016, handing over a platform in full running order. The team continued operating and evolving European Sourcing - the project was not interrupted, it simply continued without me. The final consolidation phase around shared Symfony bundles, which I had started, was carried on by the team.

With hindsight, the architectural choices made in Phase 2 proved sound and modern for their era: the service-oriented approach with dedicated subdomains, the WSSE stateless inter-service authentication, the search engine architecture and the automated supplier connector infrastructure remained technically impressive long after I had moved on.

My Critical Perspective

Honest retrospective on 8 years of development

Strengths
  • Well-designed microservices architecture

    The decomposition of the SQLI monolith into specialized services (API, search, flux, translation, export, statistics) demonstrates solid architectural vision. Each service has a clear responsibility and well-defined functional perimeter.

  • Rare end-to-end product scope

    Very few competitors at the time offered the entire B2B sourcing lifecycle within a single ecosystem. This level of integration is what positioned European Sourcing as a leader on the European market.

  • Native internationalization

    Dedicated Elasticsearch indexes per language plus a centralized translation system demonstrate a real European ambition - planned in from day one rather than retrofitted.

  • Supplier import automation

    The connectors handling heterogeneous formats (CSV, XML, API) represent considerable technical investment and core business value - a real moat against competitors.

Areas for Improvement
  • Pre-CI/CD deployment

    Manual deployment via svn up, no continuous integration pipeline, no automated testing - consistent with PHP ecosystem practices of the 2008-2014 decade, as GitHub Actions did not exist yet and CI/CD tooling (Jenkins, Travis CI) was still early.

  • Pre-SemVer versioning

    Zero Git tags across the 13 repositories - reflecting the era, before SemVer was broadly adopted in the PHP ecosystem and GitHub Releases became a standard practice.

  • Multi-framework ecosystem

    Coexistence of multiple frameworks (custom PHP, Symfony 2.4, 2.8, 3.0, 3.1, Zend Framework 1) and 2 ORMs (Propel, Doctrine) - consequence of a progressive migration spread over several years, consistent with PHP ecosystem evolution between 2010 and 2016.

What I Would Do Differently

With todays standards and hindsight, a few choices could have been made differently - each decision made sense within the constraints of its era:

  • Adopting a single framework from the start rather than maintaining a custom PHP framework alongside Symfony, though historical context justified coexistence during migration.
  • Setting up CI/CD from the GitHub migration (January 2016) - Jenkins, Travis CI or GitLab CI were available even if GitHub Actions did not exist yet.
  • Using Docker for dev and deploy environments, though Proxmox was the mature virtualization standard for PHP PME at the time.
  • Centralizing data access via a single API rather than direct MySQL from each service - a pattern that only became widespread after 2017.
Lasting Lessons

Legacy migration is a marathon

The transition from SQLI monolith to microservices architecture took 3+ years and remained in progress when I left the project. Planning realistic milestones and temporary compromises is essential.

Data import automation is critical

The supplier connectors represent considerable business value but also permanent maintenance debt - any supplier can change their format at any time, and each breakage is a production incident.

Internationalization must be planned from day one

The centralized translation system is an excellent pattern. Retrofitting multilingual support would have been exponentially more expensive than designing it upfront.

SSII documentation is precious

SQLI's specifications allowed understanding the architecture years after the end of service. Investing in technical documentation has a long-term ROI.

Technical Architecture

Architectural Évolution - Monolith to Microservices

Related journey

Professional experience linked to this achievement

Skills applied

Technical and soft skills applied

Hard Skills

Software Development5/5

Full-Stack Development

Built 15+ interconnected sub-applications spanning PHP MVC custom, Symfony 2/3, AngularJS SPA, jQuery Mobile and PhoneGap/Cordova apps over 8 years

Software Development5/5

Backend Development

Architected backend services in PHP 5.x with Symfony 2/3, Propel and Doctrine ORMs, Zend Framework legacy, RabbitMQ async processing and Memcache caching

Architecture & Design5/5

System Architecture & Design

Decomposed the SQLI monolith into a microservices ecosystem (API, search, flux, translate, export, stats, supplierbo) with shared Symfony bundles (ESCoreBundle, ESSourcingBundle) and WSSE stateless inter-service authentication

Data & AI5/5

Database Fundamentals

Designed and optimized a 97-table MySQL schema with master-slave replication - SQL normal forms (1NF/2NF/3NF/BCNF), advanced indexing (B-tree, composite, covering), constant EXPLAIN plan analysis and progression to PostgreSQL full-text (tsvector/GIN) then Elasticsearch

Architecture & Design5/5

REST API Design

Built a REST JSON API on Symfony 2.4 + Propel with WSSE stateless authentication (nonce + timestamp + digest), JMS Serializer, CORS, and multi-database connections (europeansourcing + tendanceobjet)

Software Development5/5

Advanced Algorithms & Complexity

Implemented combinatorial pricing algorithms (Cartesian product generating thousands of combinations per product: sizes × colors × quantities × marking types × marking zones × finishes) and search-engine indexing theory (inverted index, analyzers, TF-IDF scoring)

Architecture & Design4/5

Software Architecture Patterns

Applied microservices, MVC, SPA (AngularJS), Strategy pattern for 26+ heterogeneous supplier connectors (CSV/XML/API), and Doctrine behaviors (Sluggable, Sortable, Timestampable, Translatable, Blameable)

DevOps & Cloud4/5

Advanced Git Workflows

Led the migration from SVN (398 revisions) to GitHub (13 repositories, 836 commits) - organization setup, per-developer branch strategy, 20+ private repos under the medialeads organization

Image gallery

Project screenshots and visuals

Need a multilingual B2B portal designed?

I delivered the European Sourcing portal end-to-end: multilingual product modeling, sourcing catalog and buyer workflows. Let's talk about your context.

Contact me