/var/log/life.log
Блог программиста из солнечной Бурятии

Загрузка модели каталога из админского контроллера в opencart

На самом деле такое сделать без грязных хаков нельзя. Но можно пойти другим путём. Эта необходимость возникает, если нет желания дублировать и поддерживать код, который должен и с админской стороны и с фронтэнда отрабатывать. В opencart же загрузка моделей зависит от контекста, в котором происходит исполнение и $this->load->model('checkout/order'); в одном случае загрузит модель, в другом выдаст ошибку. Чтобы не дублировать код его нужно вынести в библиотеку, которая при необходимости будет проксировать запросы к ядерным моделям, в зависимости от контекста.
Читать полностью »

DHTMLX/scheduler и проблема 7 января hot fix

Описание проблемы http://habrahabr.ru/post/239423/
Толи фикс уже вышел, то ли нет, но сейчас поведение такое.

1
2
3
4
5
Tue Jan 06 2015 00:00:00 GMT+0800 (RTZ 7 (зима))
new Date(2015, 0, 7);
Wed Jan 07 2015 01:00:00 GMT+0900 (RTZ 7 (лето))
new Date(2015, 0, 8);
Thu Jan 08 2015 00:00:00 GMT+0900 (RTZ 7 (лето))

Что вызывает проблемы в методе увеличения даты в календаре.
У нас же календарь отказался уже 15 декабря работать, из-за особенностей реализации.
hot fix - перезаписать метод добавления времени в init методе
К оригиналу добавлено сравнение таймзон

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
scheduler.date.add=function(date, inc, mode){
            var ndate=new Date(date.valueOf());
            switch(mode){
                case "week":inc*=7;
                case "day":
                    ndate.setDate(ndate.getDate()+inc);
                    !date.getHours() && ndate.getHours()
                    && date.getTimezoneOffset()==ndate.getTimezoneOffset()
                    && ndate.setTime(ndate.getTime()+60 * 60 * 1000 *(24-ndate.getHours()));break;
                case "month":ndate.setMonth(ndate.getMonth()+inc);break;
                case "year":ndate.setYear(ndate.getFullYear()+inc);break;
                case "hour":ndate.setHours(ndate.getHours()+inc);break;
                case "minute":ndate.setMinutes(ndate.getMinutes()+inc);break;
                default:return scheduler.date["add_"+mode](date, inc, mode)}
                return ndate;
        }

Сборка модулей Bitrix + Git

Помимо того, что git полезен при разработке, теги git'a оказались удобны при создании обновлений для публикации в маркетплэйсе.
Каждая версия помечается соответствующим тегом. А затем скрипт по этим тегам собирает пакет обновлений.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess
import shlex
import os
import shutil
import zipfile
import sys

def converter(filePath):
    if any([filePath.endswith(extension) for extension in '.php,.sql'.split(',')]):
        with open(filePath, "rb") as F:
            text = F.read().decode("utf-8").encode("cp1251")
            if filePath.endswith('.sql'):
                filePath +=  '.cp1251'
            with open(filePath, "wb") as f:
                f.write(text)
                f.close()
        F.close()

def zipdir(path, zip, folder):
    rootlen = len(path)-len(folder) - 1
    for root, dirs, files in os.walk(path):
        for file in files:
            fn = os.path.join(root, file)
            zip.write(fn,fn[rootlen:])

def mklastversion(last_version, curdir):
    if os.path.exists(last_version):
        shutil.rmtree(last_version)
    os.mkdir(last_version)

    for item in os.listdir(curdir):
        if item!='.git' and item!='.last_version' and item!="update" and item != scriptname and item != ".gitignore":
            path = curdir+"\\"+item
            if os.path.isdir(path):
                shutil.copytree(path,last_version + "\\"+item)
            elif os.path.isfile(path):
                shutil.copy(path,last_version + "\\"+item)

    for item in os.walk(last_version):
        for f in item[2]:
            path = item[0]+"\\"+f
            converter(path)
    zip = zipfile.ZipFile(curdir+"\\.last_version.zip", 'w')
    zipdir(curdir+"\\.last_version", zip,".last_version")
    zip.close()
    shutil.move(curdir+"\\.last_version.zip",curdir+"\\.last_version")

curdir = os.path.abspath(os.curdir)
last_version = curdir +"\\.last_version"
scriptname = os.path.basename(__file__)

mklastversion(last_version, curdir)


git_tag = 'git tag'
args = shlex.split(git_tag)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
tags = p.communicate()[0].split("\n")[:-1]
if len(tags)==1 or len(tags)==0:
    sys.exit(0)
prev_version = tags[-2]
cur_version = tags[-1]

git_diff = 'git diff '+prev_version+' '+cur_version+ ' --name-only'

args = shlex.split(git_diff)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
update_list = p.communicate()[0].split("\n")[:-1]



update_path = curdir+"\\update\\"+cur_version
if os.path.exists(update_path):
    shutil.rmtree(update_path)
os.mkdir(update_path)
for filename in update_list:
    dirname = "\\".join((update_path+"\\"+filename.replace('/',"\\")).split("\\")[:-1])
    if not os.path.exists(dirname):
        os.makedirs(dirname)
    shutil.copyfile(last_version+"\\"+filename,update_path+"\\"+filename.replace('/',"\\"))
desc = raw_input("Description: ")
f = open(curdir+"\\update\\"+cur_version+"\\description.ru",'wb')
f.write(desc.decode("cp866").encode("cp1251"))
f.close()
zip = zipfile.ZipFile(curdir+"\\update\\"+cur_version+".zip", 'w')
zipdir(update_path, zip,cur_version)
zip.close()

Проблема с юзабилити

В качестве движка магазина используется virtuemart и в плане юзабилити, он далёк от идеала. Я пытался как-то это побороть. На мой взгляд получилось лучше, чем то, что предлагает виртумарт по умолчанию. Но есть одна проблема, причины которой мне не понятны.
корзина
Некоторые покупатели не видят/не понимают, что можно выбрать нужный способ оплаты:(
Уж и не знаю, чего придумать.

Лучи *** разработчикам virtuemart

Ещё во время выпуска virturmart 2 я столкнулся с их манерой релизов. Когда выпустили RC разобрался в их плохо документированном API, сделал плагин. Выпускают релизную версию, а там весь API для плагинов переделанный.
И вот опять, уже релиз кандидат, а в нём изменили xml структуру установщика, изменили незначительно, но для разных минорных версий нужен свой установщик. Само по себе это не так уж и страшно, но есть странные люди, которые ставят себе бэты и релиз кандидаты в магазины и все не объяснишь, что версия 2.9.9 это на самом деле не virtuemart 2, а будущая virtuemart 3.
Ну и баги, дыры и ломающие всё обновления.

Qiwi REST для UMI.CMS

Сделал для UMI.CMS платёжный модуль по приёму к оплате QIWI Visa Wallet. Проверялось на UMI.CMS версии 2.9.
К сожалению архитектура юми не предоставляет возможности оформить это в отдельный модуль и установить одной кнопкой, поэтому для установки мне нужен будет доступ ssh/ftp.
Обращайтесь.
Читать полностью »

Эльба – электронный бухгалтер

эльба электронный бухгалтер Из всех облачных серверов, что я пользуюсь и за которые я плачу, это amazon s3 и эльба. В амазоне бэкапы, а вот в эльба помогает мне вести бухгалтерию. Бухгалтерия, для меня, это что-то непонятное. А там сидят специально обученные люди, которые это умеют или следят за всеми обновлениями. Главное, что это всё электронное и нет необходимости ехать куда либо. Автоматические уведомления сколько и куда заплатить, какую и когда отчётность сдать. Эльба позволяет мне, далёкому от всей этой бухгалтерии, управлять с ней, да и вроде понимать, что там и куда. "Подсел" на неё когда была ещё бесплатная версия, потом на день рождения Радио-Т была раздача пользования на год. Скидки и акции там не такая уж и редкая штука, вот и сейчас тоже идёт акция, с промокодом 69405266 можно получить дополнительно 3 месяца бесплатного обслуживания.

Немного про битрикс

При запуске агентов в битрикс в $GLOBALS не создаётся USER и можно очень долго гадать и искать, почему вызванный агент не отрабатывает до конца, а падает при выполнении какого-то метода API, который где то там в кишочках битрикса использует $GLOBALS["USER"].

При публикации решений в маркетплэйсе нужно в include.php и install.php обязательно добавлять закрывающий ?> т.к. их упаковщик проверок не делает и автоматом дописывает в конец файла

1
< ? проверка деморежима ...