Refactoring the project code on 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Code Refactoring of 1C-Bitrix Project

Audit showed: init.php 3000 lines, SQL queries in templates, identical code copied in 12 components, adding new catalog field requires edits in 8 places. Refactoring — converting this chaos into maintainable codebase without changing external behavior. Key word — "without changing behavior": refactoring shouldn't break what works.

Strategy: Don't Rewrite, Replace

Full Bitrix project rewrite — trap. Business logic accumulated over years in templates and handlers, not documented. Rewriting from scratch, you'll definitely lose edge cases caught by hotfixes.

Right approach — incremental refactoring: isolate one module, rewrite it, check behavior is identical, move on. Each iteration — working site.

Refactoring Priorities

Order determined by formula: change frequency × change complexity. Files changed weekly and easy to make mistakes in — refactor first.

Priority 1: init.php Decomposition.

Typical "bad" init.php contains:

  • Event handlers (AddEventHandler)
  • Custom functions (formatting helpers, URL generation)
  • Classes (sometimes several in one file)
  • Direct initialization (connecting to external APIs on every hit)

Target state: init.php contains only autoloader require_once and handler registration. All logic — in separate classes in /local/php_interface/classes/ or /local/modules/.

Directory structure /local/:

/local/
  php_interface/
    init.php          → autoloader + registration
    classes/
      EventHandlers/  → Bitrix event handlers
      Helpers/        → utilities
      Services/       → business logic
  modules/
    project.core/     → custom project module
  components/         → custom components
  templates/          → site templates

Migration to /local/ — standard Bitrix practice. Everything in /local/ has priority over /bitrix/, allowing core updates without conflicts.

Priority 2: Extracting Logic from Component Templates.

Component template (template.php) should contain only HTML output. If it contains CIBlockElement::GetList(), $DB->Query(), complex calculations — this is problem.

Three refactoring levels:

  1. result_modifier.php — move data preparation from template.php. Simplest step, doesn't require new component.
  2. class.php — creating component class inheriting CBitrixComponent. Method executeComponent() contains logic, template.php — output only.
  3. Custom component in /local/components/project/ — when standard Bitrix component stops meeting requirements.

Priority 3: Replace Direct SQL with D7 ORM.

Direct queries via $DB->Query() — this is:

  • No escaping (SQL-injections)
  • Tied to specific DBMS
  • No caching via built-in mechanism

Replace with \Bitrix\Main\Entity\DataManager or minimally \Bitrix\Main\DB\Connection::query() with parameterized queries. For iblocks — use \Bitrix\Iblock\Elements\ElementXxxTable (D7 ORM for iblocks, available since core 21.x).

Priority 4: Eliminate Duplication.

Find via phpcpd (PHP Copy/Paste Detector) identical code blocks in different templates. Typical pattern: component catalog.section has 5 templates with 80% identical code, differing in CSS classes and field order. Solution: one template with parameters or include files for common blocks.

Safe Refactoring Process

Stage Action Control
1. Fixation Create backup + git-commit current state git init if project not in VCS
2. Tests Write smoke-tests on critical pages HTTP-statuses, key elements presence
3. Isolation Move one logic block to separate class Tests pass
4. Connection Replace old code with new class call Tests pass
5. Removal Delete old code Tests pass
6. Deploy Deploy to production Monitor errors 24 hours

Each cycle — one logical block. Don't refactor multiple things simultaneously. On production error, you must know exactly which change caused it.

Common Traps

Refactoring without VCS. Surprisingly, significant portion of Bitrix projects still not stored in Git. First refactoring step — initialize repository with correct .gitignore (exclude /bitrix/, /upload/, /vendor/, keep /local/).

D7 transition "at once". D7 API doesn't cover everything. Old API (CIBlockElement, CSale*) works and supported. Migrate to D7 only code you're refactoring — don't touch working old code for "consistency".

Refactoring without monitoring. After refactoring deploy monitor b_event_log and server logs. Errors may manifest not immediately, but under specific conditions: specific product type, certain user group, specific browser.

Timeline Estimates

Project Scale Typical Refactoring Scope Timeline
Small (up to 50 custom files) init.php decomposition, template cleanup 3-5 days
Medium (50-200 files) + SQL replacement, duplication elimination 1-2 weeks
Large (200+ files, custom modules) + /local/ migration, modular architecture 3-6 weeks

Refactoring — investment. Its effect measured not visually, but in speed of subsequent development and regression count on updates.