diff --git a/composer.json b/composer.json
index 690f8a4337..af8b82e1a0 100755
--- a/composer.json
+++ b/composer.json
@@ -71,6 +71,7 @@
"emojione/emojione": "1.3.0",
"zendframework/zend-config": "2.5.1",
+ "zendframework/zend-soap": "2.*",
"zendframework/zend-feed": "2.5.1",
"zendframework/zend-http": "2.5.1",
diff --git a/plugin/sepe/admin.php b/plugin/sepe/admin.php
new file mode 100644
index 0000000000..dae48c32f7
--- /dev/null
+++ b/plugin/sepe/admin.php
@@ -0,0 +1,13 @@
+get('sepe_enable');
+$pluginPath = api_get_path(WEB_PLUGIN_PATH).'sepe/src/menu_sepe_administracion.php';
+
+if ($enable == "true" && api_is_platform_admin()) {
+ header('Location:'.$pluginPath);
+} else {
+ header('Location: ../../index.php');
+}
+
diff --git a/plugin/sepe/config.php b/plugin/sepe/config.php
new file mode 100644
index 0000000000..4716955b4a
--- /dev/null
+++ b/plugin/sepe/config.php
@@ -0,0 +1,9 @@
+getConnection();
+$platform = $connection->getDatabasePlatform();
+
+//Create tables
+/* ========== PLUGIN_SEPE_CENTER ========== */
+$sepeCenterTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_CENTER);
+$sepeCenterTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeCenterTable->addColumn('origen_centro', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->addColumn('codigo_centro', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->addColumn('nombre_centro', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->addColumn('url', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->addColumn('url_seguimiento', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->addColumn('telefono', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->addColumn('email', \Doctrine\DBAL\Types\Type::STRING);
+$sepeCenterTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_ACTIONS ========== */
+$sepeActionsTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_ACTIONS);
+$sepeActionsTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeActionsTable->addColumn(
+ 'ORIGEN_ACCION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeActionsTable->addColumn(
+ 'CODIGO_ACCION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 30)
+);
+$sepeActionsTable->addColumn(
+ 'SITUACION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeActionsTable->addColumn(
+ 'ORIGEN_ESPECIALIDAD',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeActionsTable->addColumn(
+ 'AREA_PROFESIONAL',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 4)
+);
+$sepeActionsTable->addColumn(
+ 'CODIGO_ESPECIALIDAD',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 14)
+);
+$sepeActionsTable->addColumn(
+ 'DURACION',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeActionsTable->addColumn('FECHA_INICIO', \Doctrine\DBAL\Types\Type::DATE);
+$sepeActionsTable->addColumn('FECHA_FIN', \Doctrine\DBAL\Types\Type::DATE);
+$sepeActionsTable->addColumn(
+ 'IND_ITINERARIO_COMPLETO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+); //enum('SI','NO')
+$sepeActionsTable->addColumn(
+ 'TIPO_FINANCIACION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeActionsTable->addColumn(
+ 'NUMERO_ASISTENTES',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeActionsTable->addColumn(
+ 'DENOMINACION_ACCION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 250)
+);
+$sepeActionsTable->addColumn('INFORMACION_GENERAL', \Doctrine\DBAL\Types\Type::TEXT);
+$sepeActionsTable->addColumn('HORARIOS', \Doctrine\DBAL\Types\Type::TEXT);
+$sepeActionsTable->addColumn('REQUISITOS', \Doctrine\DBAL\Types\Type::TEXT);
+$sepeActionsTable->addColumn('CONTACTO_ACCION', \Doctrine\DBAL\Types\Type::TEXT);
+$sepeActionsTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_SPECIALTY ========== */
+$sepeSpecialtyTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_SPECIALTY);
+$sepeSpecialtyTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeSpecialtyTable->addColumn(
+ 'cod_action',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTable->addColumn(
+ 'ORIGEN_ESPECIALIDAD',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeSpecialtyTable->addColumn(
+ 'AREA_PROFESIONAL',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 4)
+);
+$sepeSpecialtyTable->addColumn(
+ 'CODIGO_ESPECIALIDAD',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 14)
+);
+$sepeSpecialtyTable->addColumn(
+ 'ORIGEN_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeSpecialtyTable->addColumn(
+ 'CODIGO_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 16)
+);
+$sepeSpecialtyTable->addColumn('FECHA_INICIO', \Doctrine\DBAL\Types\Type::DATE);
+$sepeSpecialtyTable->addColumn('FECHA_FIN', \Doctrine\DBAL\Types\Type::DATE);
+$sepeSpecialtyTable->addColumn(
+ 'MODALIDAD_IMPARTICION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HORAS_PRESENCIAL',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HORAS_TELEFORMACION',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HM_NUM_PARTICIPANTES',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HM_NUMERO_ACCESOS',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HM_DURACION_TOTAL',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HT_NUM_PARTICIPANTES',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HT_NUMERO_ACCESOS',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HT_DURACION_TOTAL',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HN_NUM_PARTICIPANTES',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HN_NUMERO_ACCESOS',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'HN_DURACION_TOTAL',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'NUM_PARTICIPANTES',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'NUMERO_ACTIVIDADES_APRENDIZAJE',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'NUMERO_INTENTOS',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->addColumn(
+ 'NUMERO_ACTIVIDADES_EVALUACION',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true, 'notnull' => false)
+);
+$sepeSpecialtyTable->setPrimaryKey(array('cod'));
+$sepeSpecialtyTable->addForeignKeyConstraint(
+ $sepeActionsTable,
+ array('cod_action'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_CENTROS ========== */
+$sepeCentrosTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_CENTROS);
+$sepeCentrosTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeCentrosTable->addColumn(
+ 'ORIGEN_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeCentrosTable->addColumn(
+ 'CODIGO_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 16)
+);
+$sepeCentrosTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_SPECIALTY_CLASSROOM ========== */
+$sepeSpecialtyClassroomTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_SPECIALTY_CLASSROOM);
+$sepeSpecialtyClassroomTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeSpecialtyClassroomTable->addColumn(
+ 'cod_specialty',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyClassroomTable->addColumn(
+ 'cod_centro',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyClassroomTable->setPrimaryKey(array('cod'));
+$sepeSpecialtyClassroomTable->addForeignKeyConstraint(
+ $sepeSpecialtyTable,
+ array('cod_specialty'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_TUTORS ========== */
+$sepeTutorsTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_TUTORS);
+$sepeTutorsTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeTutorsTable->addColumn(
+ 'cod_user_chamilo',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeTutorsTable->addColumn(
+ 'TIPO_DOCUMENTO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1)
+); //enum('D','E','U','W','G','H')
+$sepeTutorsTable->addColumn(
+ 'NUM_DOCUMENTO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 10)
+);
+$sepeTutorsTable->addColumn(
+ 'LETRA_NIF',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1)
+);
+$sepeTutorsTable->addColumn(
+ 'ACREDITACION_TUTOR',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 200)
+);
+$sepeTutorsTable->addColumn(
+ 'EXPERIENCIA_PROFESIONAL',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeTutorsTable->addColumn(
+ 'COMPETENCIA_DOCENTE',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeTutorsTable->addColumn(
+ 'EXPERIENCIA_MODALIDAD_TELEFORMACION',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeTutorsTable->addColumn(
+ 'FORMACION_MODALIDAD_TELEFORMACION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeTutorsTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_SPECIALTY_TUTORS ========== */
+$sepeSpecialtyTutorsTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_SPECIALTY_TUTORS);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'cod_specialty',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'cod_tutor',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'ACREDITACION_TUTOR',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 200)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'EXPERIENCIA_PROFESIONAL',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'COMPETENCIA_DOCENTE',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'EXPERIENCIA_MODALIDAD_TELEFORMACION',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeSpecialtyTutorsTable->addColumn(
+ 'FORMACION_MODALIDAD_TELEFORMACION',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeSpecialtyTutorsTable->setPrimaryKey(array('cod'));
+$sepeSpecialtyTutorsTable->addForeignKeyConstraint(
+ $sepeSpecialtyTable,
+ array('cod_specialty'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_TUTORS_EMPRESA ========== */
+$sepeTutorsEmpresaTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_TUTORS_EMPRESA);
+$sepeTutorsEmpresaTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeTutorsEmpresaTable->addColumn(
+ 'alias',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 255)
+);
+$sepeTutorsEmpresaTable->addColumn(
+ 'TIPO_DOCUMENTO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1, 'notnull' => false)
+); //enum('D','E','U','W','G','H')
+$sepeTutorsEmpresaTable->addColumn(
+ 'NUM_DOCUMENTO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 10, 'notnull' => false)
+);
+$sepeTutorsEmpresaTable->addColumn(
+ 'LETRA_NIF',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1, 'notnull' => false)
+);
+$sepeTutorsEmpresaTable->addColumn(
+ 'empresa',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeTutorsEmpresaTable->addColumn(
+ 'formacion',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeTutorsEmpresaTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_PARTICIPANTS ========== */
+$sepeParticipantsTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_PARTICIPANTS);
+$sepeParticipantsTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeParticipantsTable->addColumn(
+ 'cod_action',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeParticipantsTable->addColumn(
+ 'cod_user_chamilo',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeParticipantsTable->addColumn(
+ 'TIPO_DOCUMENTO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1)
+); //enum('D','E','U','W','G','H')
+$sepeParticipantsTable->addColumn(
+ 'NUM_DOCUMENTO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 10)
+);
+$sepeParticipantsTable->addColumn(
+ 'LETRA_NIF',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1)
+);
+$sepeParticipantsTable->addColumn(
+ 'INDICADOR_COMPETENCIAS_CLAVE',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeParticipantsTable->addColumn(
+ 'ID_CONTRATO_CFA',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 14, 'notnull' => false)
+);
+$sepeParticipantsTable->addColumn(
+ 'CIF_EMPRESA',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 9, 'notnull' => false)
+);
+$sepeParticipantsTable->addColumn(
+ 'cod_tutor_empresa',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeParticipantsTable->addColumn(
+ 'cod_tutor_formacion',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeParticipantsTable->setPrimaryKey(array('cod'));
+$sepeParticipantsTable->addForeignKeyConstraint(
+ $sepeActionsTable,
+ array('cod_action'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+$sepeParticipantsTable->addForeignKeyConstraint(
+ $sepeTutorsEmpresaTable,
+ array('cod_tutor_empresa'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+$sepeParticipantsTable->addForeignKeyConstraint(
+ $sepeTutorsEmpresaTable,
+ array('cod_tutor_formacion'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_PARTICIPANTS_SPECIALTY ========== */
+$sepeParticipantsSpecialtyTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_PARTICIPANTS_SPECIALTY);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'cod_participant',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'ORIGEN_ESPECIALIDAD',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'AREA_PROFESIONAL',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 4, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'CODIGO_ESPECIALIDAD',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 14, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'FECHA_ALTA',
+ \Doctrine\DBAL\Types\Type::DATE,
+ array('notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'FECHA_BAJA',
+ \Doctrine\DBAL\Types\Type::DATE,
+ array('notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'ORIGEN_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'CODIGO_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 16, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'FECHA_INICIO',
+ \Doctrine\DBAL\Types\Type::DATE,
+ array('notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'FECHA_FIN',
+ \Doctrine\DBAL\Types\Type::DATE,
+ array('notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'RESULTADO_FINAL',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 1, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'CALIFICACION_FINAL',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 4, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->addColumn(
+ 'PUNTUACION_FINAL',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 4, 'notnull' => false)
+);
+$sepeParticipantsSpecialtyTable->setPrimaryKey(array('cod'));
+$sepeParticipantsSpecialtyTable->addForeignKeyConstraint(
+ $sepeParticipantsTable,
+ array('cod_participant'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_PARTICIPANTS_SPECIALTY_TUTORIALS ========== */
+$sepeParticipantsSpecialtyTutorialsTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_PARTICIPANTS_SPECIALTY_TUTORIALS);
+$sepeParticipantsSpecialtyTutorialsTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeParticipantsSpecialtyTutorialsTable->addColumn(
+ 'cod_participant_specialty',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeParticipantsSpecialtyTutorialsTable->addColumn(
+ 'ORIGEN_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeParticipantsSpecialtyTutorialsTable->addColumn(
+ 'CODIGO_CENTRO',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 16)
+);
+$sepeParticipantsSpecialtyTutorialsTable->addColumn('FECHA_INICIO', \Doctrine\DBAL\Types\Type::DATE);
+$sepeParticipantsSpecialtyTutorialsTable->addColumn('FECHA_FIN', \Doctrine\DBAL\Types\Type::DATE);
+$sepeParticipantsSpecialtyTutorialsTable->setPrimaryKey(array('cod'));
+$sepeParticipantsSpecialtyTutorialsTable->addForeignKeyConstraint(
+ $sepeParticipantsSpecialtyTable,
+ array('cod_participant_specialty'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_COURSE_ACTIONS ========== */
+$sepeCourseActionsTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_COURSE_ACTIONS);
+$sepeCourseActionsTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeCourseActionsTable->addColumn(
+ 'id_course',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeCourseActionsTable->addColumn(
+ 'cod_action',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeCourseActionsTable->setPrimaryKey(array('cod'));
+$sepeCourseActionsTable->addForeignKeyConstraint(
+ $sepeActionsTable,
+ array('cod_action'),
+ array('cod'),
+ array('onDelete' => 'CASCADE')
+);
+
+/* ========== PLUGIN_SEPE_COMPETENCIA_DOCENTE ========== */
+$sepeCompetenciaDocenteTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_COMPETENCIA_DOCENTE);
+$sepeCompetenciaDocenteTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeCompetenciaDocenteTable->addColumn(
+ 'code',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 2)
+);
+$sepeCompetenciaDocenteTable->addColumn('valor', \Doctrine\DBAL\Types\Type::TEXT);
+$sepeCompetenciaDocenteTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_LOG_PARTICIPANT ========== */
+$sepeLogParticipantTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_LOG_PARTICIPANT);
+$sepeLogParticipantTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeLogParticipantTable->addColumn(
+ 'cod_user_chamilo',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeLogParticipantTable->addColumn(
+ 'cod_action',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeLogParticipantTable->addColumn('fecha_alta', \Doctrine\DBAL\Types\Type::DATETIME);
+$sepeLogParticipantTable->addColumn('fecha_baja', \Doctrine\DBAL\Types\Type::DATETIME);
+$sepeLogParticipantTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_LOG_MOD_PARTICIPANT ========== */
+$sepeLogModParticipantTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_LOG_MOD_PARTICIPANT);
+$sepeLogModParticipantTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeLogModParticipantTable->addColumn(
+ 'cod_user_chamilo',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeLogModParticipantTable->addColumn(
+ 'cod_action',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('unsigned' => true)
+);
+$sepeLogModParticipantTable->addColumn('fecha_mod', \Doctrine\DBAL\Types\Type::DATETIME);
+$sepeLogModParticipantTable->setPrimaryKey(array('cod'));
+
+/* ========== PLUGIN_SEPE_LOG ========== */
+$sepeLogTable = $pluginSchema->createTable(SepePlugin::TABLE_SEPE_LOG);
+$sepeLogTable->addColumn(
+ 'cod',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ array('autoincrement' => true, 'unsigned' => true)
+);
+$sepeLogTable->addColumn(
+ 'ip',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 200)
+);
+$sepeLogTable->addColumn(
+ 'action',
+ \Doctrine\DBAL\Types\Type::STRING,
+ array('length' => 255)
+);
+$sepeLogTable->addColumn('fecha', \Doctrine\DBAL\Types\Type::DATETIME);
+$sepeLogTable->setPrimaryKey(array('cod'));
+
+
+$queries = $pluginSchema->toSql($platform);
+
+foreach ($queries as $query) {
+ Database::query($query);
+}
+
+//Insert data
+$sepeCompetenciaDocenteTable = Database::get_main_table(SepePlugin::TABLE_SEPE_COMPETENCIA_DOCENTE);
+$competencias = array(
+ array(1, '01', 'Certificado de profesionalidad de docencia de la formación profesional para el empleo regulado por Real Decreto 1697/2011, de 18 de noviembre.'),
+ array(2, '02', 'Certificado de profesionalidad de formador ocupacional.'),
+ array(3, '03', 'Certificado de Aptitud Pedagágica o título profesional de Especialización Didáctica o Certificado de Cualificación Pedagógica.'),
+ array(4, '04', 'Máster Universitario habilitante para el ejercicio de las Profesiones reguladas de Profesor de Educación Secundaria Obligatoria y Bachillerato, Formación Profesional y Escuelas Oficiales de Idiomas.'),
+ array(5, '05', 'Curso de formación equivalente a la formación pedagógica y didáctica exigida para aquellas personas que, estando en posesión de una titulación declarada equivalente a efectos de docencia, no pueden realizar los estudios de máster, establecida en la disposición adicional primera del Real Decreto 1834/2008, de 8 de noviembre.'),
+ array(6, '06', 'Experiencia docente contrastada de al menos 600 horas de impartición de acciones formativas de formación profesional para el empleo o del sistema educativo en modalidad presencial, en los últimos diez años.')
+);
+
+foreach ($competencias as $competencia) {
+ Database::insert(
+ $sepeCompetenciaDocenteTable,
+ array(
+ 'cod' => $competencia[0],
+ 'code' => $competencia[1],
+ 'valor' => $competencia[2]
+
+ )
+ );
+}
+
+$sepeTutorsEmpresaTable = Database::get_main_table(SepePlugin::TABLE_SEPE_TUTORS_EMPRESA);
+ Database::insert(
+ $sepeTutorsEmpresaTable,
+ array(
+ 'cod' => 1,
+ 'alias' => 'Sin tutor',
+ 'empresa' => 'SI',
+ 'formacion' => 'SI'
+ )
+ );
+
+/* Crear campos extras a los usuarios de la plataforma */
+
+$fieldlabel = 'sexo';
+$fieldtype = '3';
+$fieldtitle = 'Género';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+$sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', 'Hombre', 'Hombre',1);";
+Database::query($sql);
+$sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', 'Mujer', 'Mujer',2);";
+Database::query($sql);
+$sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', 'Otros', 'Otros',3);";
+Database::query($sql);
+
+$fieldlabel = 'edad';
+$fieldtype = '6';
+$fieldtitle = 'Fecha de nacimiento';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'nivel_formativo';
+$fieldtype = '1';
+$fieldtitle = 'Nivel formativo';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'situacion_laboral';
+$fieldtype = '1';
+$fieldtitle = 'Situación Laboral';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'provincia_residencia';
+$fieldtype = '4';
+$fieldtitle = 'Provincia Residencia';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$provincias = 'Albacete;Alicante/Alacant;Almería;Araba/Álava;Asturias;Ávila;Badajoz;Balears, Illes;Barcelona;Bizkaia;Burgos;Cáceres;Cádiz;Cantabria;Castellón/Castelló;Ciudad Real;Córdoba;Coruña, A;Cuenca;Gipuzkoa;Girona;Granada;Guadalajara;Huelva;Huesca;Jaén;León;Lleida;Lugo;Madrid;Málaga;Murcia;Navarra;Ourense;Palencia;Palmas, Las;Pontevedr;Rioja, La;Salamanca;Santa Cruz de Tenerife;Segovia;Sevilla;Soria;Tarragona;Teruel;Toledo;Valencia/Valéncia;Valladolid;Zamora;Zaragoza;Ceuta;Melilla';
+$list_provincias = explode(';',$provincias);
+$i = 1;
+foreach($list_provincias as $value){
+ $sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', '".$i."', '".$value."','".$i."');";
+ Database::query($sql);
+ $i++;
+}
+
+$fieldlabel = 'comunidad_residencia';
+$fieldtype = '4';
+$fieldtitle = 'Comunidad autonoma de residencia';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+$ccaa = ';Andalucía;Aragón;Asturias, Principado de;Balears, Illes;Canarias;Cantabria;Castilla y León;Castilla - La Mancha;Cataluña;Comunitat Valenciana;Extremadura;Galicia;Madrid, Comunidad de;Murcia, Región de;Navarra, Comunidad Foral de;País Vasco;Rioja, La;Ceuta;Melilla';
+$list_ccaa = explode(';',$ccaa);
+$i = 1;
+foreach($list_ccaa as $value){
+ $sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', '".$i."', '".$value."','".$i."');";
+ Database::query($sql);
+ $i++;
+}
+
+
+$fieldlabel = 'provincia_trabajo';
+$fieldtype = '4';
+$fieldtitle = 'Provincia Trabajo';
+$fielddefault = '';
+//$fieldoptions = ';Albacete;Alicante/Alacant;Almería;Araba/Álava;Asturias;Ávila;Badajoz;Balears, Illes;Barcelona;Bizkaia;Burgos;Cáceres;Cádiz;Cantabria;Castellón/Castelló;Ciudad Real;Córdoba;Coruña, A;Cuenca;Gipuzkoa;Girona;Granada;Guadalajara;Huelva;Huesca;Jaén;León;Lleida;Lugo;Madrid;Málaga;Murcia;Navarra;Ourense;Palencia;Palmas, Las;Pontevedr;Rioja, La;Salamanca;Santa Cruz de Tenerife;Segovia;Sevilla;Soria;Tarragona;Teruel;Toledo;Valencia/Valéncia;Valladolid;Zamora;Zaragoza;Ceuta;Melilla';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+$i = 1;
+foreach($list_provincias as $value){
+ $sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', '".$i."', '".$value."','".$i."');";
+ Database::query($sql);
+ $i++;
+}
+
+$fieldlabel = 'comunidad_trabajo';
+$fieldtype = '4';
+$fieldtitle = 'Comunidad autonoma Trabajo';
+$fielddefault = '';
+//$fieldoptions = ';Andalucía;Aragón;Asturias, Principado de;Balears, Illes;Canarias;Cantabria;Castilla y León;Castilla - La Mancha;Cataluña;Comunitat Valenciana;Extremadura;Galicia;Madrid, Comunidad de;Murcia, Región de;Navarra, Comunidad Foral de;País Vasco;Rioja, La;Ceuta;Melilla';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+$i = 1;
+foreach($list_ccaa as $value){
+ $sql = "INSERT INTO extra_field_options (field_id, option_value, display_text, option_order) VALUES ('".$field_id."', '".$i."', '".$value."','".$i."');";
+ Database::query($sql);
+ $i++;
+}
+
+$fieldlabel = 'medio_conocimiento';
+$fieldtype = '2';
+$fieldtitle = 'Medio de conocimiento Acción formativa';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'experiencia_anterior';
+$fieldtype = '2';
+$fieldtitle = 'Experiencia anterior en la realización de cursos on-line';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'razones_teleformacion';
+$fieldtype = '2';
+$fieldtitle = 'Razones por la modalidad teleformación';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'valoracion_modalidad';
+$fieldtype = '2';
+$fieldtitle = 'Valoración general sobre la modalidad';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'categoria_profesional';
+$fieldtype = '1';
+$fieldtitle = 'Categoría profesional';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'tamano_empresa';
+$fieldtype = '1';
+$fieldtitle = 'Tamaño de la empresa';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
+
+$fieldlabel = 'horario_accion_formativa';
+$fieldtype = '1';
+$fieldtitle = 'Horario de la acción formativa';
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel,$fieldtype,$fieldtitle,$fielddefault);
diff --git a/plugin/sepe/index.php b/plugin/sepe/index.php
new file mode 100644
index 0000000000..79900374cd
--- /dev/null
+++ b/plugin/sepe/index.php
@@ -0,0 +1,7 @@
+install();
diff --git a/plugin/sepe/js/sepe.js b/plugin/sepe/js/sepe.js
new file mode 100644
index 0000000000..c8d015fb77
--- /dev/null
+++ b/plugin/sepe/js/sepe.js
@@ -0,0 +1,224 @@
+/* For licensing terms, see /license.txt */
+/**
+ * JS library for the Chamilo sepe plugin
+ * @package chamilo.plugin.sepe
+ */
+$(document).ready(function () {
+ $("#borrar_datos_identificativos").click(function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ if(confirm("Confirme si desea borrar todos los datos identificativos del centro y las acciones formativas creadas")){
+ $.post("function.php", {tab: "borra_datos_centro"},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ alert(data.content);
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $("#borrar_accion_formativa").click(function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $("#cod_action").val();
+ if(confirm("Confirme si desea borrar la acción formativa y todos los datos almacenados.")){
+ $.post("function.php", {tab: "borra_accion_formativa", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ window.location.replace("listado-acciones-formativas.php");
+ //location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $(".del_specialty").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id");
+ if(confirm("Confirme si desea borrar la especialidad de la acción formativa y todos los datos de centros almacenados.")){
+ $.post("function.php", {tab: "borra_especialidad_accion", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ alert(data.content);
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $(".del_classroom").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id");
+ if(confirm("Confirme si desea borrar el centro presencial de la especialidad de la acción formativa.")){
+ $.post("function.php", {tab: "borra_especialidad_classroom", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ alert(data.content);
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $(".del_tutor").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id");
+ if(confirm("Confirme si desea borrar los datos del tutor de la especialidad de la acción formativa.")){
+ $.post("function.php", {tab: "borra_especialidad_tutor", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ alert(data.content);
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $(".del_participant").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id");
+ if(confirm("Confirme si desea borrar el participante de la acción formativa y todos los datos almacenados.")){
+ $.post("function.php", {tab: "borra_participante_accion", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ alert(data.content);
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $(".del_specialty_participant").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id");
+ if(confirm("Confirme si desea borrar la especialidad del participante.")){
+ $.post("function.php", {tab: "borra_especialidad_participante", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ alert(data.content);
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $(".asignar_action_formativa").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcourse = $(this).prop("id");
+ vaction = $(this).parent().prev().children().val();
+ if(vaction != ''){
+ $.post("function.php", {tab: "asignar_accion", cod_course:vcourse, cod_action:vaction},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ location.reload();
+ }
+ }, "json");
+ }else{
+ alert("Seleccione una accion formativa del desplegable");
+ }
+ });
+
+ $(".desvincular_accion").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id");
+ $.post("function.php", {tab: "desvincular_action", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ location.reload();
+ }
+ }, "json");
+ });
+
+ $(".del_action_formativa").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ vcod = $(this).prop("id").substr(3);
+ if(confirm("Confirme si desea borrar la acci\u00F3n formativa y desvincular del curso actual")){
+ $.post("function.php", {tab: "borra_accion_formativa", cod:vcod},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ location.reload();
+ }
+ }, "json");
+ }
+ });
+
+ $("#slt_user_existente").change(function(){
+ if($(this).val() == "NO"){
+ $("#box_datos_tutor").show();
+ $("#box_listado_tutores").hide();
+ }else{
+ $("#box_listado_tutores").show();
+ $("#box_datos_tutor").hide();
+ }
+ });
+
+ $(".info_tutor").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ $(this).parent().parent().next().toggle("slow");
+ });
+
+ $("#slt_centro_existente").change(function(){
+ if($(this).val() == "NO"){
+ $("#box_datos_centro").show();
+ $("#box_listado_centros").hide();
+ }else{
+ $("#box_listado_centros").show();
+ $("#box_datos_centro").hide();
+ }
+ });
+
+ $('form[name="form_participant_action"] input[type="submit"]').click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ if($('#cod_user_chamilo').val() == ''){
+ alert("Debe indicar un usuario de chamilo del curso con el que corresponda");
+ }else{
+ $('form[name="form_participant_action"]').submit();
+ }
+ });
+
+ $("#generar_key_sepe").click(function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ $.post("function.php", {tab: "generar_api_key_sepe"},
+ function (data) {
+ if (data.status == "false") {
+ alert(data.content);
+ } else {
+ $("#input_key").val(data.content);
+ }
+ }, "json");
+ });
+
+});
+
diff --git a/plugin/sepe/lang/english.php b/plugin/sepe/lang/english.php
new file mode 100644
index 0000000000..3a01db4b8c
--- /dev/null
+++ b/plugin/sepe/lang/english.php
@@ -0,0 +1,43 @@
+Plugins)
+ * @package chamilo.plugin.sepe
+ */
+/**
+ * Plugin details (must be present)
+ */
+require_once dirname(__FILE__) . '/config.php';
+$plugin_info = SepePlugin::create()->get_info();
+
diff --git a/plugin/sepe/readme.txt b/plugin/sepe/readme.txt
new file mode 100644
index 0000000000..5832f3ae31
--- /dev/null
+++ b/plugin/sepe/readme.txt
@@ -0,0 +1,24 @@
+Plugin que conecta el SEPE con la plataforma de formación Chamilo.
+
+Integra:
+- Conexiones SOAP
+- Formularios para editar datos
+
+Instrucciones:
+- Instalar plugin
+- En configuración del plugin: Habilitar Sepe -> SI -> Guardar
+- Seleccionar una región del plugin -> menu_administrator
+- Crear un usuario llamado SEPE con perfil de recursos humanos.
+- Ir al menú del plugin Sepe (en la sección de plugin activos en administración) y seleccionar el link de "Configuración" -> Generar API key. Usar esta clave para realizar pruebas con el SOAP.
+- En el fichero /plugin/sepe/ws/ProveedorCentroTFWS.wsdl modificar la linea 910 para indicar el dominio de la plataforma sustituyendo la cadena ##midominio## por el dominio que corresponda.
+
+Composer:
+- Es necesario incluir (en el caso de que no estuviera añadido) en el fichero composer.json en el apartado de "require" bajo la linea "zendframework/zend-config": "2.3.3", insertar "zendframework/zend-soap": "2.*",
+- A continuación habrá que actualizar desde la linea de comandos el directorio vendor, usando la orden 'composer update'
+
+Verificación del Webservices:
+- Para verificar que el webservice está activo, habrá que entrar desde un navegador web a la siguiente dirección:
+http://dominioquecorresponda/plugin/sepe/ws/service.php
+
+
+
diff --git a/plugin/sepe/resources/button_delete.gif b/plugin/sepe/resources/button_delete.gif
new file mode 100644
index 0000000000..e07331a7c9
Binary files /dev/null and b/plugin/sepe/resources/button_delete.gif differ
diff --git a/plugin/sepe/resources/edit.png b/plugin/sepe/resources/edit.png
new file mode 100644
index 0000000000..6f48cdf1cc
Binary files /dev/null and b/plugin/sepe/resources/edit.png differ
diff --git a/plugin/sepe/resources/folder.png b/plugin/sepe/resources/folder.png
new file mode 100644
index 0000000000..c0854974d1
Binary files /dev/null and b/plugin/sepe/resources/folder.png differ
diff --git a/plugin/sepe/resources/forms.png b/plugin/sepe/resources/forms.png
new file mode 100644
index 0000000000..32042b377d
Binary files /dev/null and b/plugin/sepe/resources/forms.png differ
diff --git a/plugin/sepe/resources/icon-delete.png b/plugin/sepe/resources/icon-delete.png
new file mode 100644
index 0000000000..eecdee87e9
Binary files /dev/null and b/plugin/sepe/resources/icon-delete.png differ
diff --git a/plugin/sepe/resources/icon-edit.png b/plugin/sepe/resources/icon-edit.png
new file mode 100644
index 0000000000..16f9487ef1
Binary files /dev/null and b/plugin/sepe/resources/icon-edit.png differ
diff --git a/plugin/sepe/resources/list.png b/plugin/sepe/resources/list.png
new file mode 100644
index 0000000000..5539f7a0e2
Binary files /dev/null and b/plugin/sepe/resources/list.png differ
diff --git a/plugin/sepe/resources/options-lines.png b/plugin/sepe/resources/options-lines.png
new file mode 100644
index 0000000000..09985a940c
Binary files /dev/null and b/plugin/sepe/resources/options-lines.png differ
diff --git a/plugin/sepe/resources/plugin.css b/plugin/sepe/resources/plugin.css
new file mode 100644
index 0000000000..e8bdddc760
--- /dev/null
+++ b/plugin/sepe/resources/plugin.css
@@ -0,0 +1,127 @@
+.cleared{
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ line-height:0;
+}
+.campo_texto{
+ color: #00829c;
+ font-size: 1.3em;
+ font-weight: normal;
+ padding-top: 2px;
+}
+
+.sepe_borrar_link {
+ background: url("icon-delete.png") no-repeat scroll 0px 10px;
+ padding-left: 30px;
+ font-size:1.3em;
+}
+.sepe_editar_link {
+ background: url("icon-edit.png") no-repeat scroll 0 10px;
+ padding-left: 30px;
+ font-size:1.3em;
+}
+.sepe_listado_link {
+ background: url("options-lines.png") no-repeat scroll 0 10px;
+ padding-left: 30px;
+ font-size:1.3em;
+}
+input.btn_menu_lateral{
+ width:100%;
+ margin-bottom:10px;
+}
+legend.subcampo {
+ font-size: 16px;
+ line-height: 16px;
+ padding-bottom: 10px;
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 0;
+}
+.well.subcampo {
+ background: none repeat scroll 0 0 #fafafa;
+}
+em.span4 {
+ float: none;
+ margin: 0;
+ padding: 5px;
+ display:inline-block;
+}
+em{
+ float: none;
+ margin: 5px 0 0 0;
+ padding: 5px;
+ display: block;
+}
+.mensaje_info{
+ padding:5px 10px;
+}
+.slt_fecha {
+ width:auto;
+ display:inline-block;
+}
+textarea.accion_formativa, input.accion_formativa {
+ margin-bottom: 5px;
+ width: 95%;
+}
+
+input.numerico {
+ text-align: center;
+ width: 60px;
+}
+
+.subcampo2 {
+ font-size: 16px;
+ text-align: center;
+}
+
+.mlateral{
+ margin: 0 5px;
+}
+
+#tabla_info_nif{
+ width:90%;
+ margin:5px auto;
+}
+
+#tabla_info_nif td, #tabla_info_nif th {
+ background: none repeat scroll 0 0 white;
+ border: 1px solid;
+ color: #333;
+ font-weight: bold;
+ text-align:center;
+}
+
+.va_middle, .table td.va_middle{
+ vertical-align:middle;
+}
+
+.box_centrado{
+ margin:0 auto;
+}
+
+
+.dinline{
+ display:inline;
+}
+
+.fright{
+ float:right;
+}
+
+.cursor{
+ cursor:pointer;
+}
+
+.ta-center{
+ text-align:center;
+}
+
+.mtop5{
+ margin-top:5px;
+}
+
+
+
diff --git a/plugin/sepe/resources/settings.png b/plugin/sepe/resources/settings.png
new file mode 100644
index 0000000000..236cd54824
Binary files /dev/null and b/plugin/sepe/resources/settings.png differ
diff --git a/plugin/sepe/src/accion-formativa.php b/plugin/sepe/src/accion-formativa.php
new file mode 100644
index 0000000000..23034e8071
--- /dev/null
+++ b/plugin/sepe/src/accion-formativa.php
@@ -0,0 +1,60 @@
+get_lang('accion_formativa');
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $tpl = new Template($templateName);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $tpl->assign('info', $info);
+ $tpl->assign('fecha_start', date("d/m/Y",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('fecha_end', date("d/m/Y",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('cod_action', $cod_action);
+ $listSpecialty = listSpecialty($cod_action);
+ $tpl->assign('listSpecialty', $listSpecialty);
+ $listParticipant = listParticipant($cod_action);
+ $tpl->assign('listParticipant', $listParticipant);
+
+
+ $listing_tpl = 'sepe/view/accion_formativa.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/configuracion.php b/plugin/sepe/src/configuracion.php
new file mode 100644
index 0000000000..ca2f93ef5a
--- /dev/null
+++ b/plugin/sepe/src/configuracion.php
@@ -0,0 +1,41 @@
+ 0)
+ {
+ $tmp = Database::fetch_assoc($result);
+ $info = $tmp['api'];
+
+ } else {
+ $info = '';
+ }
+ $templateName = $plugin->get_lang('configuracion_sepe');
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $tpl = new Template($templateName);
+
+ $tpl->assign('info', $info);
+
+ $listing_tpl = 'sepe/view/configuracion.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/datos-identificativos.php b/plugin/sepe/src/datos-identificativos.php
new file mode 100644
index 0000000000..6da0eb22fd
--- /dev/null
+++ b/plugin/sepe/src/datos-identificativos.php
@@ -0,0 +1,37 @@
+get_lang('datos_centro');
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $tpl = new Template($templateName);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $tpl->assign('info', $info);
+
+ $listing_tpl = 'sepe/view/datos_identificativos.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
+
diff --git a/plugin/sepe/src/editar-accion-formativa.php b/plugin/sepe/src/editar-accion-formativa.php
new file mode 100644
index 0000000000..eeb09072ce
--- /dev/null
+++ b/plugin/sepe/src/editar-accion-formativa.php
@@ -0,0 +1,112 @@
+get_lang('new_accion_formativa');
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $tpl = new Template($templateName);
+ $inicio_anio = $fin_anio = date("Y");
+ $tpl->assign('info', $info);
+ $tpl->assign('new_action', 'SI');
+ $tpl->assign('id_course', $_GET['cid']);
+ } else {
+ $id_course = obtener_course($_GET['cod_action']);
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ $info = accion_formativa($_GET['cod_action']);
+ $templateName = $plugin->get_lang('editar_accion_formativa');
+ $tpl = new Template($templateName);
+ $tpl->assign('info', $info);
+ $tpl->assign('day_start', date("j",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('month_start', date("n",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('year_start', date("Y",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('day_end', date("j",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('month_end', date("n",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('year_end', date("Y",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('new_action', 'NO');
+ $inicio_anio = date("Y",strtotime($info['FECHA_INICIO']));
+ $fin_anio = date("Y",strtotime($info['FECHA_FIN']));
+ }
+
+ $lista_anio = array();
+ if ($inicio_anio > $fin_anio) {
+ $tmp = $inicio_anio;
+ $inicio_anio = $fin_anio;
+ $fin_anio = $tmp;
+ }
+ $inicio_anio -= 5;
+ $fin_anio += 5;
+ $fin_rango_anio = (($inicio_anio + 15) < $fin_anio) ? ($fin_anio+1):($inicio_anio +15);
+ while ($inicio_anio <= $fin_rango_anio) {
+ $lista_anio[] = $inicio_anio;
+ $inicio_anio++;
+ }
+ $tpl->assign('list_year', $lista_anio);
+
+ $listing_tpl = 'sepe/view/editar_accion_formativa.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/editar-datos-identificativos.php b/plugin/sepe/src/editar-datos-identificativos.php
new file mode 100644
index 0000000000..5c06a136b6
--- /dev/null
+++ b/plugin/sepe/src/editar-datos-identificativos.php
@@ -0,0 +1,67 @@
+ "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "datos-identificativos.php", "name" => $plugin->get_lang('datos_centro'));
+
+
+ $info = datos_identificativos();
+ $templateName = $plugin->get_lang('editar_datos_centro');
+ $tpl = new Template($templateName);
+
+ $tpl->assign('info', $info);
+
+ $listing_tpl = 'sepe/view/editar_datos_identificativos.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
+
diff --git a/plugin/sepe/src/editar-especialidad-accion.php b/plugin/sepe/src/editar-especialidad-accion.php
new file mode 100644
index 0000000000..b53c040781
--- /dev/null
+++ b/plugin/sepe/src/editar-especialidad-accion.php
@@ -0,0 +1,145 @@
+ "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ if (isset($_GET['new_specialty']) && $_GET['new_specialty']=="SI") {
+ $templateName = $plugin->get_lang('new_specialty_accion');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $info = array();
+ $tpl->assign('info', $info);
+ $tpl->assign('new_action', 'SI');
+ $inicio_anio = $fin_anio = date("Y");
+ } else {
+ $templateName = $plugin->get_lang('edit_specialty_accion');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $info = especialidad_accion($_GET['cod_specialty']);
+ $tpl->assign('info', $info);
+ if ($info['FECHA_INICIO']!='0000-00-00' && $info['FECHA_INICIO']!=NULL) {
+ $tpl->assign('day_start', date("j",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('month_start', date("n",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('year_start', date("Y",strtotime($info['FECHA_INICIO'])));
+ $inicio_anio = date("Y",strtotime($info['FECHA_INICIO']));
+ } else {
+ $inicio_anio = date("Y");
+ }
+ if ($info['FECHA_FIN']!='0000-00-00' && $info['FECHA_FIN']!=NULL) {
+ $tpl->assign('day_end', date("j",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('month_end', date("n",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('year_end', date("Y",strtotime($info['FECHA_FIN'])));
+ $fin_anio = date("Y",strtotime($info['FECHA_FIN']));
+ } else {
+ $fin_anio = date("Y");
+ }
+ $tpl->assign('new_action', 'NO');
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+
+ $listClassroom = listClassroom($_GET['cod_specialty']);
+ $tpl->assign('listClassroom', $listClassroom);
+ $listTutors = listTutors($_GET['cod_specialty']);
+ $tpl->assign('listTutors', $listTutors);
+ }
+
+ $lista_anio = array();
+ if ($inicio_anio > $fin_anio) {
+ $tmp = $inicio_anio;
+ $inicio_anio = $fin_anio;
+ $fin_anio = $tmp;
+ }
+ $inicio_anio -= 5;
+ $fin_anio += 5;
+ $fin_rango_anio = (($inicio_anio + 15) < $fin_anio) ? ($fin_anio+1):($inicio_anio +15);
+ while ($inicio_anio <= $fin_rango_anio) {
+ $lista_anio[] = $inicio_anio;
+ $inicio_anio++;
+ }
+ $tpl->assign('list_year', $lista_anio);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+
+ $listing_tpl = 'sepe/view/editar_especialidad_accion.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/editar-especialidad-classroom.php b/plugin/sepe/src/editar-especialidad-classroom.php
new file mode 100644
index 0000000000..b40e18775e
--- /dev/null
+++ b/plugin/sepe/src/editar-especialidad-classroom.php
@@ -0,0 +1,123 @@
+0) {
+ $aux = Database::fetch_assoc($rs_tmp);
+ $cod_centro = $aux['cod'];
+ } else {
+ $params = array(
+ 'ORIGEN_CENTRO' => $ORIGEN_CENTRO,
+ 'CODIGO_CENTRO' => $CODIGO_CENTRO,
+ );
+ $cod_centro = Database::insert('plugin_sepe_centros', $params);
+ }
+
+ if (isset($new_classroom) && $new_classroom!="SI") {
+ $sql = "UPDATE plugin_sepe_specialty_classroom SET cod_centro='".$cod_centro."' WHERE cod='".$cod_classroom."';";
+ } else {
+ $sql = "INSERT INTO plugin_sepe_specialty_classroom (cod_specialty, cod_centro) VALUES ('".$cod_specialty."','".$cod_centro."');";
+ }
+ //echo $sql;
+ //exit;
+
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Database::error();
+ $_SESSION['sepe_message_error'] = "No se ha guardado los cambios";
+ } else {
+ $_SESSION['sepe_message_info'] = "Se ha guardado los cambios";
+ if ($new_classroom=="SI") {
+ $cod_classroom = Database::insert_id();
+ }
+ }
+ }
+ session_write_close();
+ $id_course = obtener_course($cod_action);
+ header("Location: editar-especialidad-accion.php?new_specialty=NO&cod_specialty=".$cod_specialty."&cod_action=".$cod_action);
+
+}
+
+
+
+if (api_is_platform_admin()) {
+ $id_course = obtener_course($_GET['cod_action']);
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ $interbreadcrumb[] = array("url" => "editar-especialidad-accion.php?new_specialty=NO&cod_specialty=".$_GET['cod_specialty']."&cod_action=".$_GET['cod_action'], "name" => $plugin->get_lang('especialidad_accion_formativa'));
+ if (isset($_GET['new_classroom']) && $_GET['new_classroom']=="SI") {
+ $templateName = $plugin->get_lang('new_specialty_classroom');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $info = array();
+ $tpl->assign('info', $info);
+ $tpl->assign('new_classroom', 'SI');
+ } else {
+ $templateName = $plugin->get_lang('edit_specialty_classroom');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $tpl->assign('cod_classroom', $_GET['cod_classroom']);
+ $info = especialidad_classroom($_GET['cod_classroom']);
+ $tpl->assign('info', $info);
+ $tpl->assign('new_classroom', 'NO');
+
+ }
+ $listCentros = listado_centros();
+
+ $tpl->assign('listCentrosExistentes', $listCentros);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $listing_tpl = 'sepe/view/editar_especialidad_classroom.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/editar-especialidad-participante.php b/plugin/sepe/src/editar-especialidad-participante.php
new file mode 100644
index 0000000000..86fd64d8bf
--- /dev/null
+++ b/plugin/sepe/src/editar-especialidad-participante.php
@@ -0,0 +1,170 @@
+ "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ $interbreadcrumb[] = array("url" => "editar-participante-accion.php?new_participant=NO&cod_participant=".$_GET['cod_participant']."&cod_action=".$_GET['cod_action'], "name" => $plugin->get_lang('participante_accion_formativa'));
+ if (isset($_GET['new_specialty']) && $_GET['new_specialty']=="SI") {
+ $templateName = $plugin->get_lang('new_specialty_participant');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_participant', $_GET['cod_participant']);
+ $info = array();
+ $tpl->assign('info', $info);
+ $tpl->assign('new_specialty', 'SI');
+ $inicio_anio = $fin_anio = date("Y");
+ $alta_anio = $baja_anio = date("Y");
+ } else {
+ $templateName = $plugin->get_lang('edit_specialty_participant');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $tpl->assign('cod_participant', $_GET['cod_participant']);
+ $info = especialidad_participante($_GET['cod_specialty']);
+ //error_log(print_r($info,true));
+ $tpl->assign('info', $info);
+ $tpl->assign('new_specialty', 'NO');
+ if ($info['FECHA_ALTA']!='0000-00-00' && $info['FECHA_ALTA']!=NULL) {
+ $tpl->assign('day_alta', date("j",strtotime($info['FECHA_ALTA'])));
+ $tpl->assign('month_alta', date("n",strtotime($info['FECHA_ALTA'])));
+ $tpl->assign('year_alta', date("Y",strtotime($info['FECHA_ALTA'])));
+ $alta_anio = date("Y",strtotime($info['FECHA_ALTA']));
+ } else {
+ $alta_anio = date("Y");
+ }
+ if ($info['FECHA_BAJA']!='0000-00-00' && $info['FECHA_BAJA']!=NULL) {
+ $tpl->assign('day_baja', date("j",strtotime($info['FECHA_BAJA'])));
+ $tpl->assign('month_baja', date("n",strtotime($info['FECHA_BAJA'])));
+ $tpl->assign('year_baja', date("Y",strtotime($info['FECHA_BAJA'])));
+ $baja_anio = date("Y",strtotime($info['FECHA_BAJA']));
+ } else {
+ $baja_anio = date("Y");
+ }
+ if ($info['FECHA_INICIO']!='0000-00-00' && $info['FECHA_INICIO']!=NULL) {
+ $tpl->assign('day_start', date("j",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('month_start', date("n",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('year_start', date("Y",strtotime($info['FECHA_INICIO'])));
+ $inicio_anio = date("Y",strtotime($info['FECHA_INICIO']));
+ } else {
+ $inicio_anio = date("Y");
+ }
+ if ($info['FECHA_FIN']!='0000-00-00' && $info['FECHA_FIN']!=NULL) {
+ $tpl->assign('day_end', date("j",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('month_end', date("n",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('year_end', date("Y",strtotime($info['FECHA_FIN'])));
+ $fin_anio = date("Y",strtotime($info['FECHA_FIN']));
+ } else {
+ $fin_anio = date("Y");
+ }
+ $listSpecialtyTutorials = listSpecialtyTutorial($_GET['cod_specialty']);
+ $tpl->assign('listSpecialtyTutorials', $listSpecialtyTutorials);
+ }
+
+
+ $lista_anio = array();
+ if ($alta_anio > $baja_anio) {
+ $tmp = $alta_anio;
+ $alta_anio = $baja_anio;
+ $baja_anio = $tmp;
+ }
+ $alta_anio -= 5;
+ $baja_anio += 5;
+ $fin_rango_anio = (($alta_anio + 15) < $baja_anio) ? ($baja_anio+1):($alta_anio + 15);
+ while ($alta_anio <= $fin_rango_anio) {
+ $lista_anio[] = $alta_anio;
+ $alta_anio++;
+ }
+ $tpl->assign('list_year', $lista_anio);
+
+ $lista_anio = array();
+ if ($inicio_anio > $fin_anio) {
+ $tmp = $inicio_anio;
+ $inicio_anio = $fin_anio;
+ $fin_anio = $tmp;
+ }
+ $inicio_anio -= 5;
+ $fin_anio += 5;
+ $fin_rango_anio = (($inicio_anio + 15) < $fin_anio) ? ($fin_anio+1):($inicio_anio +15);
+ while ($inicio_anio <= $fin_rango_anio) {
+ $lista_anio[] = $inicio_anio;
+ $inicio_anio++;
+ }
+ $tpl->assign('list_year_2', $lista_anio);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $listing_tpl = 'sepe/view/editar_especialidad_participante.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/editar-especialidad-tutor.php b/plugin/sepe/src/editar-especialidad-tutor.php
new file mode 100644
index 0000000000..36efe0d2dd
--- /dev/null
+++ b/plugin/sepe/src/editar-especialidad-tutor.php
@@ -0,0 +1,146 @@
+0) {
+ //datos identificativos existen se actualizan
+ $aux = Database::fetch_assoc($rs);
+ $sql = "UPDATE plugin_sepe_tutors SET
+ cod_user_chamilo='".$cod_user_chamilo."',
+ ACREDITACION_TUTOR='".$ACREDITACION_TUTOR."',
+ EXPERIENCIA_PROFESIONAL='".$EXPERIENCIA_PROFESIONAL."',
+ COMPETENCIA_DOCENTE='".$COMPETENCIA_DOCENTE."',
+ EXPERIENCIA_MODALIDAD_TELEFORMACION='".$EXPERIENCIA_MODALIDAD_TELEFORMACION."',
+ FORMACION_MODALIDAD_TELEFORMACION='".$FORMACION_MODALIDAD_TELEFORMACION."'
+ WHERE cod='".$aux['cod']."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Database::error();
+ exit;
+ $_SESSION['sepe_message_error'] = "No se ha guardado los cambios";
+ }
+ $cod_tutor = $aux['cod'];
+ } else {
+ //datos identificativos no existen se crea un nuevo registro
+ Database::query('UPDATE plugin_sepe_tutors SET cod_user_chamilo="" WHERE cod_user_chamilo="'.$cod_user_chamilo.'"');
+ $sql = "INSERT INTO plugin_sepe_tutors (cod_user_chamilo,TIPO_DOCUMENTO,NUM_DOCUMENTO,LETRA_NIF,ACREDITACION_TUTOR,EXPERIENCIA_PROFESIONAL,COMPETENCIA_DOCENTE,EXPERIENCIA_MODALIDAD_TELEFORMACION,FORMACION_MODALIDAD_TELEFORMACION)
+ VALUES
+ ('".$cod_user_chamilo."','".$TIPO_DOCUMENTO."','".$NUM_DOCUMENTO."','".$LETRA_NIF."','".$ACREDITACION_TUTOR."','".$EXPERIENCIA_PROFESIONAL."','".$COMPETENCIA_DOCENTE."','".$EXPERIENCIA_MODALIDAD_TELEFORMACION."','".$FORMACION_MODALIDAD_TELEFORMACION."');";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Database::error();
+ $_SESSION['sepe_message_error'] = "No se ha guardado los cambios";
+ }
+ $cod_tutor = Database::insert_id();
+ }
+
+ if (isset($new_tutor) && $new_tutor!="SI") {
+ $sql = "UPDATE plugin_sepe_specialty_tutors SET
+ cod_tutor='".$cod_tutor."',
+ ACREDITACION_TUTOR='".$ACREDITACION_TUTOR."',
+ EXPERIENCIA_PROFESIONAL='".$EXPERIENCIA_PROFESIONAL."',
+ COMPETENCIA_DOCENTE='".$COMPETENCIA_DOCENTE."',
+ EXPERIENCIA_MODALIDAD_TELEFORMACION='".$EXPERIENCIA_MODALIDAD_TELEFORMACION."',
+ FORMACION_MODALIDAD_TELEFORMACION='".$FORMACION_MODALIDAD_TELEFORMACION."'
+ WHERE cod='".$cod_s_tutor."';";
+ } else {
+ $sql = "INSERT INTO plugin_sepe_specialty_tutors (cod_specialty,cod_tutor,ACREDITACION_TUTOR,EXPERIENCIA_PROFESIONAL,COMPETENCIA_DOCENTE,EXPERIENCIA_MODALIDAD_TELEFORMACION,FORMACION_MODALIDAD_TELEFORMACION)
+ VALUES
+ ('".$cod_specialty."','".$cod_tutor."','".$ACREDITACION_TUTOR."','".$EXPERIENCIA_PROFESIONAL."','".$COMPETENCIA_DOCENTE."','".$EXPERIENCIA_MODALIDAD_TELEFORMACION."','".$FORMACION_MODALIDAD_TELEFORMACION."');";
+
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Database::error();
+ $_SESSION['sepe_message_error'] = "No se ha guardado los cambios";
+ } else {
+ $_SESSION['sepe_message_info'] = "Se ha guardado los cambios";
+ if ($new_tutor=="SI") {
+ $cod_tutor = Database::insert_id();
+ //$sql = "INSERT INTO plugin_sepe_specialty_tutors (cod_specialty, cod_tutor) VALUES ('".$cod_specialty."','".$cod_tutor."');";
+ //$res = Database::query($sql);
+ }
+ }
+ }
+ session_write_close();
+ $id_course = obtener_course($cod_action);
+ header("Location: editar-especialidad-accion.php?new_specialty=NO&cod_specialty=".$cod_specialty."&cod_action=".$cod_action);
+}
+
+if (api_is_platform_admin()) {
+ $id_course = obtener_course($_GET['cod_action']);
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ $interbreadcrumb[] = array("url" => "editar-especialidad-accion.php?new_specialty=NO&cod_specialty=".$_GET['cod_specialty']."&cod_action=".$_GET['cod_action'], "name" => $plugin->get_lang('especialidad_accion_formativa'));
+ if (isset($_GET['new_tutor']) && $_GET['new_tutor']=="SI") {
+ $templateName = $plugin->get_lang('new_specialty_tutor');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $info = array();
+ $tpl->assign('info', $info);
+ $tpl->assign('new_tutor', 'SI');
+ $inicio_anio = date("Y");
+ $cod_profesor_chamilo = '';
+ } else {
+ $templateName = $plugin->get_lang('edit_specialty_tutor');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $tpl->assign('cod_tutor', $_GET['cod_tutor']);
+ $info = especialidad_tutor($_GET['cod_tutor']);
+ $tpl->assign('info', $info);
+ $tpl->assign('new_tutor', 'NO');
+ $cod_profesor_chamilo = $info['cod_user_chamilo'];
+ }
+ $listTutores = listado_tutores_specialty($_GET['cod_specialty']);
+ $tpl->assign('listTutorsExistentes', $listTutores);
+
+ $course_code = obtener_course_code($_GET['cod_action']);
+ $listProfesor = CourseManager::get_teacher_list_from_course_code($course_code);
+ $listProfesor = limpiarAsignadosProfesores($listProfesor,$_GET['cod_specialty'],$cod_profesor_chamilo);
+ $tpl->assign('listProfesor', $listProfesor);
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $listing_tpl = 'sepe/view/editar_especialidad_tutor.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/editar-especialidad-tutorials.php b/plugin/sepe/src/editar-especialidad-tutorials.php
new file mode 100644
index 0000000000..6bf3b035de
--- /dev/null
+++ b/plugin/sepe/src/editar-especialidad-tutorials.php
@@ -0,0 +1,112 @@
+ "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ $interbreadcrumb[] = array("url" => "editar-especialidad-participante.php?new_specialty=NO&cod_participant=".$cod_participant."&cod_specialty=".$_GET['cod_specialty']."&cod_action=".$_GET['cod_action'], "name" => $plugin->get_lang('participante_especialidad_formativa'));
+ if (isset($_GET['new_tutorial']) && $_GET['new_tutorial']=="SI") {
+ $templateName = $plugin->get_lang('new_tutorial');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $info = array();
+ $tpl->assign('info', $info);
+ $tpl->assign('new_tutorial', 'SI');
+ $inicio_anio = date("Y");
+ } else {
+ $templateName = $plugin->get_lang('edit_tutorial');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $tpl->assign('cod_specialty', $_GET['cod_specialty']);
+ $tpl->assign('cod_tutorial', $_GET['cod_tutorial']);
+ $info = especialidad_tutorial($_GET['cod_tutorial']);
+ $tpl->assign('info', $info);
+ $tpl->assign('new_tutorial', 'NO');
+ if ($info['FECHA_INICIO']!='0000-00-00' && $info['FECHA_INICIO']!=NULL) {
+ $tpl->assign('day_start', date("j",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('month_start', date("n",strtotime($info['FECHA_INICIO'])));
+ $tpl->assign('year_start', date("Y",strtotime($info['FECHA_INICIO'])));
+ $inicio_anio = date("Y",strtotime($info['FECHA_INICIO']));
+ } else {
+ $inicio_anio = date("Y");
+ }
+ if ($info['FECHA_FIN']!='0000-00-00' && $info['FECHA_FIN']!=NULL) {
+ $tpl->assign('day_end', date("j",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('month_end', date("n",strtotime($info['FECHA_FIN'])));
+ $tpl->assign('year_end', date("Y",strtotime($info['FECHA_FIN'])));
+ }
+ }
+ $lista_anio = array();
+ $fin_anio = $inicio_anio + 10;
+ while ($inicio_anio < $fin_anio) {
+ $lista_anio[] = $inicio_anio;
+ $inicio_anio++;
+ }
+ $tpl->assign('list_year', $lista_anio);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $listing_tpl = 'sepe/view/editar_especialidad_tutorials.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/editar-participante-accion.php b/plugin/sepe/src/editar-participante-accion.php
new file mode 100644
index 0000000000..8097fed890
--- /dev/null
+++ b/plugin/sepe/src/editar-participante-accion.php
@@ -0,0 +1,171 @@
+";
+ echo var_dump($_POST);
+ echo "";
+ */
+ reset ($_POST);
+ while (list ($param, $val) = each ($_POST)) {
+ $valor = Database::escape_string($_POST[$param]);
+ $asignacion = "\$" . $param . "='" . $valor . "';";
+ //echo $asignacion;
+ eval($asignacion);
+ }
+
+ if (isset($cod_tutor_empresa) && $cod_tutor_empresa=="nuevo_tutor_empresa") {
+ $sql = "SELECT * FROM plugin_sepe_tutors_empresa
+ WHERE TIPO_DOCUMENTO='".$TE_TIPO_DOCUMENTO."' AND NUM_DOCUMENTO='".$TE_NUM_DOCUMENTO."' AND LETRA_NIF='".$TE_LETRA_NIF."';";
+ $rs = Database::query($sql);
+ if (Database::num_rows($rs)>0) {
+ $row = Database::fetch_assoc($rs);
+ $cod_tutor_empresa = $row['cod'];
+ $sql = "UPDATE plugin_sepe_tutors_empresa SET empresa='SI' WHERE cod='".$cod_tutor_empresa."'";
+ Database::query($sql);
+ } else {
+ $sql = "INSERT INTO plugin_sepe_tutors_empresa (alias,TIPO_DOCUMENTO,NUM_DOCUMENTO,LETRA_NIF,empresa)
+ VALUES ('".$TE_alias."','".$TE_TIPO_DOCUMENTO."','".$TE_NUM_DOCUMENTO."','".$TE_LETRA_NIF."','SI');";
+ $rs = Database::query($sql);
+ if (!$rs) {
+ echo Database::error();
+ } else {
+ $cod_tutor_empresa = Database::insert_id();
+ }
+ }
+ }
+
+ if (isset($cod_tutor_formacion) && $cod_tutor_formacion=="nuevo_tutor_formacion") {
+ $sql = "SELECT * FROM plugin_sepe_tutors_empresa
+ WHERE TIPO_DOCUMENTO='".$TF_TIPO_DOCUMENTO."' AND NUM_DOCUMENTO='".$TF_NUM_DOCUMENTO."' AND LETRA_NIF='".$TF_LETRA_NIF."';";
+ $rs = Database::query($sql);
+
+ if (Database::num_rows($rs)>0) {
+ $row = Database::fetch_assoc($rs);
+ $cod_tutor_formacion = $row['cod'];
+ $sql = "UPDATE plugin_sepe_tutors_empresa SET formacion='SI' WHERE cod='".$cod_tutor_formacion."'";
+ Database::query($sql);
+ } else {
+ $sql = "INSERT INTO plugin_sepe_tutors_empresa (alias,TIPO_DOCUMENTO,NUM_DOCUMENTO,LETRA_NIF,formacion)
+ VALUES ('".$TF_alias."','".$TF_TIPO_DOCUMENTO."','".$TF_NUM_DOCUMENTO."','".$TF_LETRA_NIF."','SI');";
+ $rs = Database::query($sql);
+ if (!$rs) {
+ echo Database::error();
+ } else {
+ $cod_tutor_formacion = Database::insert_id();
+ }
+ }
+ }
+
+ if (isset($new_participant) && $new_participant!="SI") {
+ $sql = "UPDATE plugin_sepe_participants SET cod_user_chamilo='".$cod_user_chamilo."', TIPO_DOCUMENTO='".$TIPO_DOCUMENTO."', NUM_DOCUMENTO='".$NUM_DOCUMENTO."', LETRA_NIF='".$LETRA_NIF."', INDICADOR_COMPETENCIAS_CLAVE='".$INDICADOR_COMPETENCIAS_CLAVE."', ID_CONTRATO_CFA='".$ID_CONTRATO_CFA."', CIF_EMPRESA='".$CIF_EMPRESA."', cod_tutor_empresa='".$cod_tutor_empresa."', cod_tutor_formacion='".$cod_tutor_formacion."' WHERE cod='".$cod_participant."';";
+ } else {
+ $sql = "INSERT INTO plugin_sepe_participants(cod_action,cod_user_chamilo,TIPO_DOCUMENTO,NUM_DOCUMENTO,LETRA_NIF,INDICADOR_COMPETENCIAS_CLAVE,ID_CONTRATO_CFA,CIF_EMPRESA,cod_tutor_empresa,cod_tutor_formacion)
+ VALUES ('".$cod_action."','".$cod_user_chamilo."','".$TIPO_DOCUMENTO."','".$NUM_DOCUMENTO."','".$LETRA_NIF."','".$INDICADOR_COMPETENCIAS_CLAVE."','".$ID_CONTRATO_CFA."','".$CIF_EMPRESA."','".$cod_tutor_empresa."','".$cod_tutor_formacion."');";
+ }
+
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Database::error();
+ $_SESSION['sepe_message_error'] = "No se ha guardado los cambios";
+ } else {
+ $_SESSION['sepe_message_info'] = "Se ha guardado los cambios";
+ if ($new_participant=="SI") {
+ $cod_participant = Database::insert_id();
+ $sql = "INSERT INTO plugin_sepe_log_participant (cod_user_chamilo, cod_action, fecha_alta) VALUES ('".$cod_user_chamilo."','".$cod_action."','".date("Y-m-d H:i:s")."');";
+ $res = Database::query($sql);
+ } else {
+ $sql = "INSERT INTO plugin_sepe_log_mod_participant (cod_user_chamilo, cod_action, fecha_mod) VALUES ('".$cod_user_chamilo."','".$cod_action."','".date("Y-m-d H:i:s")."');";
+ $res = Database::query($sql);
+ }
+ }
+ session_write_close();
+ $id_course = obtener_course($cod_action);
+ header("Location: editar-participante-accion.php?new_participant=NO&cod_participant=".$cod_participant."&cod_action=".$cod_action);
+
+}
+
+
+
+if (api_is_platform_admin()) {
+ $id_course = obtener_course($_GET['cod_action']);
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $interbreadcrumb[] = array("url" => "listado-acciones-formativas.php", "name" => $plugin->get_lang('listado_acciones_formativas'));
+ $interbreadcrumb[] = array("url" => "accion-formativa.php?cid=".$id_course, "name" => $plugin->get_lang('accion_formativa'));
+ if (isset($_GET['new_participant']) && $_GET['new_participant']=="SI") {
+ $templateName = $plugin->get_lang('new_participant_accion');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $info = array();
+ $tpl->assign('info', $info);
+ $tpl->assign('new_participant', 'SI');
+ } else {
+ $templateName = $plugin->get_lang('edit_participant_accion');
+ $tpl = new Template($templateName);
+ $tpl->assign('cod_action', $_GET['cod_action']);
+ $info = participante_accion($_GET['cod_participant']);
+ $tpl->assign('info', $info);
+ $tpl->assign('new_participant', 'NO');
+ $tpl->assign('cod_participant', $_GET['cod_participant']);
+
+ if ($info['cod_user_chamilo'] != 0) {
+ $info_usuario_chamilo = api_get_user_info($info['cod_user_chamilo']);//UserManager::get_user_info_by_id($info['cod_user_chamilo']);
+ $tpl->assign('info_user_chamilo', $info_usuario_chamilo);
+ }
+
+ $listParticipantSpecialty = listParticipantSpecialty($_GET['cod_participant']);
+ $tpl->assign('listParticipantSpecialty', $listParticipantSpecialty);
+ }
+ $course_code = obtener_course_code($_GET['cod_action']);
+ //$cod_curso = obtener_course($_GET['cod_action']);
+ $listAlumnoInfo = array();
+ $listAlumno = CourseManager::get_student_list_from_course_code($course_code);
+
+ foreach ($listAlumno as $value) {
+ $sql = "SELECT 1 FROM plugin_sepe_participants WHERE cod_user_chamilo='".$value['user_id']."';";
+ $res = Database::query($sql);
+ if (Database::num_rows($res)==0) {
+ $listAlumnoInfo[] = api_get_user_info($value['user_id']); //UserManager::get_user_info_by_id($value['user_id']);
+ }
+ }
+ /*
+ echo "";
+ echo var_dump($listAlumnoInfo);
+ echo "
";
+ exit;
+ */
+ $tpl->assign('listAlumno', $listAlumnoInfo);
+ $listTutorE = array();
+ $listTutorE = listadoTutorE();
+ $tpl->assign('listTutorE', $listTutorE);
+ $listTutorF = array();
+ $listTutorF= listadoTutorE("formacion='SI'");
+ $tpl->assign('listTutorF', $listTutorF);
+
+ if (isset($_SESSION['sepe_message_info'])) {
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])) {
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+
+ $listing_tpl = 'sepe/view/editar_participante_accion.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/function.php b/plugin/sepe/src/function.php
new file mode 100644
index 0000000000..f13dcd5fc6
--- /dev/null
+++ b/plugin/sepe/src/function.php
@@ -0,0 +1,225 @@
+get_lang('ProblemToDeleteInfoCenter') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'borra_accion_formativa') {
+ $cod = $_REQUEST['cod'];
+ $sql = "DELETE FROM $tableSepeActions WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDeleteInfoAction') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ $_SESSION['sepe_message_info'] = $content;
+ echo json_encode(array("status" => "true"));
+ }
+}
+
+if ($_REQUEST['tab'] == 'borra_especialidad_accion') {
+ $cod = substr($_REQUEST['cod'],9);
+ $sql = "DELETE FROM $tableSepeSpecialty WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDeleteInfoSpecialty') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'borra_especialidad_participante') {
+ $cod = substr($_REQUEST['cod'],9);
+ $sql = "DELETE FROM $tableSepeParticipantsSpecialty WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDeleteInfoSpecialty') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'borra_especialidad_classroom') {
+ $cod = substr($_REQUEST['cod'],9);
+ $sql = "DELETE FROM $tableSepeSpecialtyClassroom WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDeleteInfoSpecialtyClassroom') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'comprobar_editar_tutor') {
+ //$cod = substr($_REQUEST['cod'],9);
+ $tipo = $_REQUEST['tipo'];
+ $num = $_REQUEST['num'];
+ $letra=$_REQUEST['letra'];
+ $codchamilo = $_REQUEST['codchamilo'];
+
+ $sql = "SELECT cod_user_chamilo FROM $tableSepeTutors WHERE TIPO_DOCUMENTO='".$tipo."' AND NUM_DOCUMENTO='".$num."' AND LETRA_NIF='".$letra."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemDataBase') . Database::error();
+ error_log(print_r($content,1));
+ exit;
+ } else {
+ $aux = Database::fetch_assoc($res);
+ if ($aux['cod_user_chamilo']==$codchamilo || $aux['cod_user_chamilo']=='0') {
+ echo json_encode(array("status" => "true"));
+ } else {
+ $content = $plugin->get_lang('ModDataTeacher');
+ echo json_encode(array("status" => "false", "content" => $content));
+ }
+ }
+}
+
+if ($_REQUEST['tab'] == 'borra_especialidad_tutor') {
+ $cod = substr($_REQUEST['cod'],5);
+ $sql = "DELETE FROM $tableSepeSpecialtyTutors WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDeleteInfoSpecialtyTutor') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'borra_participante_accion') {
+ $cod = substr($_REQUEST['cod'],11);
+ $sql = "SELECT cod_user_chamilo, cod_action FROM $tableSepeParticipants WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $row = Database::fetch_assoc($res);
+
+ $sql = "UPDATE plugin_sepe_log_participant SET fecha_baja='".date("Y-m-d H:i:s")."' WHERE cod_user_chamilo='".$row['cod_user_chamilo']."' AND cod_action='".$row['cod_action']."';";
+ $res = Database::query($sql);
+
+ $sql = "DELETE FROM $tableSepeParticipants WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDeleteInfoParticipant') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'desvincular_action') {
+ $cod = substr($_REQUEST['cod'],3);
+ $sql = "DELETE FROM $tableSepeCourseActions WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ if (!$res) {
+ $content = $plugin->get_lang('ProblemToDesvincularInfoAction') . Database::error();
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $content = $plugin->get_lang('DeleteOk');
+ echo json_encode(array("status" => "true", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'asignar_accion') {
+ $id_course = substr($_REQUEST['cod_course'],11);
+ $cod_action = $_REQUEST['cod_action'];
+
+ if (trim($cod_action)!='' && trim($id_course)!='') {
+ $cod_action = Database::escape_string($cod_action);
+ $id_course = Database::escape_string($id_course);
+ $sql = "SELECT * FROM $tableSepeCourseActions WHERE cod_action='".$cod_action."';";
+
+ $rs = Database::query($sql);
+ if (Database::num_rows($rs) > 0) {
+ $content = "La acción formativa elegida está siendo usada por otro curso";
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $sql = "SELECT 1 FROM course WHERE id='".$id_course."';";
+ $rs = Database::query($sql);
+ if (Database::num_rows($rs) == 0) {
+ $content = "El curso al que se le asocia la acción formativa no existe";
+ echo json_encode(array("status" => "false", "content" => $content));
+ } else {
+ $sql = "INSERT INTO $tableSepeCourseActions (id_course, cod_action) VALUES ('".$id_course."','".$cod_action."');";
+ $rs = Database::query($sql);
+ if (!$rs) {
+ $content = "No se ha podido guardar la selección";
+ echo json_encode(array("status" => "false", "content" => utf8_encode($content)));
+ } else {
+ echo json_encode(array("status" => "true"));
+ }
+ }
+ }
+ } else {
+ $content = "Error al recibir los datos";
+ echo json_encode(array("status" => "false", "content" => $content));
+ }
+}
+
+if ($_REQUEST['tab'] == 'generar_api_key_sepe') {
+ $tApi = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
+ //$info_user = UserManager::get_user_info('SEPE');
+ $info_user = api_get_user_info_from_username('SEPE');
+
+ $array_list_key = array();
+ $user_id = $info_user['user_id'];
+ $api_service = 'dokeos';
+ $num = UserManager::update_api_key($user_id, $api_service);
+ $array_list_key = UserManager::get_api_keys($user_id, $api_service);
+
+ if (trim($array_list_key[$num])!='') {
+ $content = $array_list_key[$num];
+ echo json_encode(array("status" => "true", "content" => $content));
+ } else {
+ $content = "Problema al generar una nueva api key";
+ echo json_encode(array("status" => "false", "content" => $content));
+ }
+}
diff --git a/plugin/sepe/src/index.php b/plugin/sepe/src/index.php
new file mode 100644
index 0000000000..6fd199e66e
--- /dev/null
+++ b/plugin/sepe/src/index.php
@@ -0,0 +1 @@
+get('sepe_enable');
+$title="Administración SEPE";
+$pluginPath = api_get_path(WEB_PLUGIN_PATH).'sepe/src/';
+if (api_is_platform_admin() && $is_enable=="true") {
+ echo '';
+ echo '
';
+ echo '
'.$title.'
';
+ echo '';
+ echo '
';
+ echo '
';
+}
+
diff --git a/plugin/sepe/src/listado-acciones-formativas.php b/plugin/sepe/src/listado-acciones-formativas.php
new file mode 100644
index 0000000000..9157e5bebd
--- /dev/null
+++ b/plugin/sepe/src/listado-acciones-formativas.php
@@ -0,0 +1,53 @@
+get_lang('listado_acciones_formativas');
+ $interbreadcrumb[] = array("url" => "/plugin/sepe/src/menu_sepe_administracion.php", "name" => $plugin->get_lang('menu_sepe'));
+ $tpl = new Template($templateName);
+
+ if (isset($_SESSION['sepe_message_info'])){
+ $tpl->assign('message_info', $_SESSION['sepe_message_info']);
+ unset($_SESSION['sepe_message_info']);
+ }
+ if (isset($_SESSION['sepe_message_error'])){
+ $tpl->assign('message_error', $_SESSION['sepe_message_error']);
+ unset($_SESSION['sepe_message_error']);
+ }
+
+ $lista_curso_acciones = listCourseAction();
+ /*
+ echo "";
+ echo var_dump($lista_curso_acciones);
+ echo "
";
+ exit;
+ */
+ $lista_curso_libre_acciones = listCourseFree();
+ $lista_acciones_libres = listActionFree();
+
+ $tpl->assign('lista_curso_acciones', $lista_curso_acciones);
+ $tpl->assign('lista_curso_libre_acciones', $lista_curso_libre_acciones);
+ $tpl->assign('lista_acciones_libres', $lista_acciones_libres);
+
+ $listing_tpl = 'sepe/view/listado_acciones_formativas.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/menu_sepe_administracion.php b/plugin/sepe/src/menu_sepe_administracion.php
new file mode 100644
index 0000000000..ac0b8d5218
--- /dev/null
+++ b/plugin/sepe/src/menu_sepe_administracion.php
@@ -0,0 +1,59 @@
+get('sepe_enable');
+$title="Administración SEPE";
+$pluginPath = api_get_path(WEB_PLUGIN_PATH).'sepe/src/';
+
+if (api_is_platform_admin()) {
+ $html_text = '';
+ $html_text .= '';
+ $html_text .= '
';
+ $html_text .= '
'.$title.'
';
+ $html_text .= '';
+ $html_text .= '
';
+ $html_text .= '
';
+ $html_text .= '
';
+ $html_text .= '
';
+ $html_text .= '
';
+ $html_text .= '
';
+
+ $templateName = $plugin->get_lang('menu_sepe_administracion');
+ $interbreadcrumb[] = array("url" => "/main/admin/index.php", "name" => get_lang('Administration'));
+ $tpl = new Template($templateName);
+ $tpl->assign('html_text', $html_text);
+
+ $listing_tpl = 'sepe/view/menu_sepe_administracion.tpl';
+ $content = $tpl->fetch($listing_tpl);
+ $tpl->assign('content', $content);
+ $tpl->display_one_col_template();
+
+} else {
+ header("location: http://".$_SERVER['SERVER_NAME']);
+}
diff --git a/plugin/sepe/src/sepe.lib.php b/plugin/sepe/src/sepe.lib.php
new file mode 100644
index 0000000000..7ba0d0e143
--- /dev/null
+++ b/plugin/sepe/src/sepe.lib.php
@@ -0,0 +1,587 @@
+ 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function obtener_cod_action($cod)
+{
+ global $tableSepeCourseActions;
+ $sql = "SELECT cod_action FROM $tableSepeCourseActions WHERE id_course='".$cod."';";
+ $rs = Database::query($sql);
+ $aux = Database::fetch_assoc($rs);
+ return $aux['cod_action'];
+}
+
+function obtener_course($cod)
+{
+ global $tableSepeCourseActions;
+ $sql = "SELECT id_course FROM $tableSepeCourseActions WHERE cod_action='".$cod."';";
+ $rs = Database::query($sql);
+ $aux = Database::fetch_assoc($rs);
+ return $aux['id_course'];
+}
+function obtener_course_code($cod)
+{
+ global $tableCourse;
+ $course_id = obtener_course($cod);
+ $sql = "SELECT code FROM $tableCourse WHERE id='".$course_id."'";
+ $rs = Database::query($sql);
+ $aux = Database::fetch_assoc($rs);
+ return $aux['code'];
+}
+
+function obtener_participant($cod)
+{
+ global $tableSepeParticipantsSpecialty;
+ $sql = "SELECT cod_participant FROM $tableSepeParticipantsSpecialty WHERE cod='".$cod."';";
+ $rs = Database::query($sql);
+ $aux = Database::fetch_assoc($rs);
+ return $aux['cod_participant'];
+}
+
+function accion_formativa($cod)
+{
+ global $tableSepeActions;
+ $sql = "SELECT * FROM $tableSepeActions WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function especialidad_accion($cod)
+{
+ global $tableSepeSpecialty;
+ $sql = "SELECT * FROM $tableSepeSpecialty WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function especialidad_classroom($cod)
+{
+ global $tableSepeSpecialtyClassroom;
+ global $tableCentros;
+ $sql = "SELECT a.*,ORIGEN_CENTRO,CODIGO_CENTRO FROM $tableSepeSpecialtyClassroom a LEFT JOIN $tableCentros b
+ ON a.cod_centro=b.cod WHERE a.cod='".$cod."';";
+ //echo $sql; exit;
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function especialidad_tutorial($cod)
+{
+ global $tableSepeParticipantsSpecialtyTutorials;
+ $sql = "SELECT * FROM $tableSepeParticipantsSpecialtyTutorials WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function list_tutor($cod_specialty)
+{
+ global $tableSepeSpecialtyTutors;
+ $sql = "SELECT * FROM $tableSepeSpecialtyTutors WHERE cod_specialty='".$cod_specialty."';";
+ $res = Database::query($sql);
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function listado_centros()
+{
+ global $tableCentros;
+ $sql = "SELECT * FROM $tableCentros;";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+function listadoTutorE($cond="empresa='SI'")
+{
+ global $tableTutorE;
+ $sql = "SELECT * FROM $tableTutorE WHERE ".$cond." ORDER BY alias ASC, NUM_DOCUMENTO ASC;";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $tmp = array();
+ $tmp['cod'] = $row['cod'];
+ if (trim($row['alias'])!='') {
+ $tmp['alias'] = $row['alias'].' - '.$row['TIPO_DOCUMENTO'].' '.$row['NUM_DOCUMENTO'].' '.$row['LETRA_NIF'];
+ } else {
+ $tmp['alias'] = $row['TIPO_DOCUMENTO'].' '.$row['NUM_DOCUMENTO'].' '.$row['LETRA_NIF'];
+ }
+ $aux[] = $tmp;
+ }
+ return $aux;
+}
+
+function listadoTutorF()
+{
+ global $tableTutorE;
+ $sql = "SELECT * FROM $tableTutorE WHERE formacion='SI' ORDER BY alias ASC, NUM_DOCUMENTO ASC;";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $tmp = array();
+ $tmp['cod'] = $row['cod'];
+ if (trim($row['alias'])!='') {
+ $tmp['alias'] = $row['alias'].' - '.$row['TIPO_DOCUMENTO'].' '.$row['NUM_DOCUMENTO'].' '.$row['LETRA_NIF'];
+ } else {
+ $tmp['alias'] = $row['TIPO_DOCUMENTO'].' '.$row['NUM_DOCUMENTO'].' '.$row['LETRA_NIF'];
+ }
+ $aux[] = $tmp;
+ }
+ return $aux;
+}
+
+function listado_tutores()
+{
+ global $tableSepeTutors;
+ global $tableUser;
+ $sql = "SELECT a.*, b.firstname AS firstname, b.lastname AS lastname
+ FROM $tableSepeTutors AS a, $tableUser AS b
+ WHERE a.cod_user_chamilo=b.user_id;";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+function listado_tutores_specialty($cod_specialty)
+{
+ global $tableSepeSpecialtyTutors;
+ global $tableSepeTutors;
+ global $tableUser;
+ $sql = "SELECT cod_tutor FROM $tableSepeSpecialtyTutors;";
+ $rs = Database::query($sql);
+ $lista_tutores = array();
+ while ($tmp = Database::fetch_assoc($rs)) {
+ $lista_tutores[] = $tmp['cod_tutor'];
+ }
+ $sql = "SELECT a.*, b.firstname AS firstname, b.lastname AS lastname
+ FROM $tableSepeTutors AS a LEFT JOIN $tableUser AS b ON a.cod_user_chamilo=b.user_id;";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ if (!in_array($row['cod'],$lista_tutores)) {
+ $tutor = array();
+ $tutor['cod'] = $row['cod'];
+ if (trim($row['firstname'])!='' || trim($row['lastname'])!='') {
+ $tutor['datos'] = $row['firstname'].' '.$row['lastname'].' ('.$row['TIPO_DOCUMENTO'].' '.$row['NUM_DOCUMENTO'].' '.$row['LETRA_NIF'].' )';
+ } else {
+ $tutor['datos'] = $row['TIPO_DOCUMENTO'].' '.$row['NUM_DOCUMENTO'].' '.$row['LETRA_NIF'];
+ }
+ $aux[] = $tutor;
+ }
+ }
+ return $aux;
+}
+
+function especialidad_tutor($cod)
+{
+ global $tableSepeSpecialtyTutors;
+ global $tableSepeTutors;
+ $sql = "SELECT a.*,cod_user_chamilo,TIPO_DOCUMENTO,NUM_DOCUMENTO,LETRA_NIF FROM $tableSepeSpecialtyTutors a
+ INNER JOIN $tableSepeTutors b ON a.cod_tutor=b.cod
+ WHERE a.cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function limpiarAsignadosProfesores($listProfesor,$cod_specialty,$cod_profesor_chamilo)
+{
+ global $tableSepeSpecialtyTutors;
+ global $tableSepeTutors;
+ $sql = "SELECT cod_tutor FROM $tableSepeSpecialtyTutors WHERE cod_specialty='".$cod_specialty."';";
+ $rs = Database::query($sql);
+ if (Database::num_rows($rs)>0) {
+ while ($aux = Database::fetch_assoc($rs)) {
+ $sql = "SELECT cod_user_chamilo FROM $tableSepeTutors WHERE cod='".$aux['cod_tutor']."';";
+ $res = Database::query($sql);
+ if (Database::num_rows($res)>0) {
+ $tmp = Database::fetch_assoc($res);
+ if ($tmp['cod_user_chamilo']!=$cod_profesor_chamilo) {
+ unset($listProfesor[$tmp['cod_user_chamilo']]);
+ }
+ }
+ }
+ }
+ return $listProfesor;
+}
+
+function participante_accion($cod)
+{
+ global $tableSepeParticipants;
+ $sql = "SELECT * FROM $tableSepeParticipants WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function especialidad_participante($cod)
+{
+ global $tableSepeParticipantsSpecialty;
+ $sql = "SELECT * FROM $tableSepeParticipantsSpecialty WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function tutorias_especialidad_participante($cod)
+{
+ global $tableSepeParticipantsSpecialtyTutorials;
+ $sql = "SELECT * FROM $tableSepeParticipantsSpecialtyTutorials WHERE cod='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function existeDatosIdentificativos()
+{
+ global $tableSepeCenter;
+ $sql = "SELECT 1 FROM $tableSepeCenter;";
+ $result = Database::query($sql);
+ if ( Database::affected_rows($result) > 0 ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * List specialties
+ * @return array Results (list of specialty details)
+ */
+function listSpecialty($cod)
+{
+ global $tableSepeSpecialty;
+ $sql = "SELECT cod, ORIGEN_ESPECIALIDAD, AREA_PROFESIONAL, CODIGO_ESPECIALIDAD
+ FROM $tableSepeSpecialty
+ WHERE cod_action='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+/**
+ * List participants
+ * @return array Results (list of participants details)
+ */
+function listParticipant($cod)
+{
+ global $tableSepeParticipants;
+ global $tableUser;
+ $sql = "SELECT cod, TIPO_DOCUMENTO, NUM_DOCUMENTO, LETRA_NIF, firstname, lastname
+ FROM $tableSepeParticipants LEFT JOIN $tableUser ON $tableSepeParticipants.cod_user_chamilo=$tableUser.user_id
+ WHERE cod_action='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+/**
+ * List classroom
+ * @return array Results (list of classroom details)
+ */
+function listClassroom($cod)
+{
+ global $tableSepeSpecialtyClassroom;
+ global $tableCentros;
+ $sql = "SELECT a.*,ORIGEN_CENTRO,CODIGO_CENTRO FROM $tableSepeSpecialtyClassroom a LEFT JOIN $tableCentros b
+ ON a.cod_centro=b.cod WHERE cod_specialty='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+/**
+ * List tutors
+ * @return array Results (list of tutors details)
+ */
+function listTutors($cod)
+{
+ global $tableSepeSpecialtyTutors;
+ global $tableSepeTutors;
+ global $tableUser;
+ $aux = array();
+ $sql = "SELECT a.*,TIPO_DOCUMENTO,NUM_DOCUMENTO,LETRA_NIF, firstname, lastname FROM $tableSepeSpecialtyTutors a
+ INNER JOIN $tableSepeTutors b ON a.cod_tutor=b.cod
+ LEFT JOIN $tableUser c ON b.cod_user_chamilo=c.user_id
+ WHERE a.cod_specialty='".$cod."';";
+ $res = Database::query($sql);
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+/**
+ * List participants specialty
+ * @return array Results (list of participants specialty details)
+ */
+function listParticipantSpecialty($cod)
+{
+ global $tableSepeParticipantsSpecialty;
+ $sql = "SELECT * FROM $tableSepeParticipantsSpecialty WHERE cod_participant='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+/**
+ * List participants specialty
+ * @return array Results (list of participants specialty details)
+ */
+function listSpecialtyTutorial($cod)
+{
+ global $tableSepeParticipantsSpecialtyTutorials;
+ $sql = "SELECT * FROM $tableSepeParticipantsSpecialtyTutorials WHERE cod_participant_specialty='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+/**
+ * List of courses associated with formative actions
+ * @return array Results (list of courses id)
+ */
+function listCourseAction()
+{
+ global $tableSepeActions;
+ global $tableSepeCourseActions;
+ //global ;
+ //$table = Database::get_main_table(TABLE_SEPE_COURSE_ACTIONS);
+ $sql = "SELECT $tableSepeCourseActions.*, course.title AS title, $tableSepeActions.ORIGEN_ACCION AS ORIGEN_ACCION, $tableSepeActions.CODIGO_ACCION AS CODIGO_ACCION
+ FROM $tableSepeCourseActions, course, $tableSepeActions
+ WHERE $tableSepeCourseActions.id_course=course.id AND $tableSepeActions.cod=$tableSepeCourseActions.cod_action";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+function listCourseFree()
+{
+ global $tableCourse;
+ global $tableSepeCourseActions;
+ $sql = "SELECT id, title FROM $tableCourse
+ WHERE NOT EXISTS (
+ SELECT * FROM $tableSepeCourseActions WHERE $tableCourse.id = $tableSepeCourseActions.id_course)
+ ;";
+ $res = Database::query($sql);
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+
+function listActionFree()
+{
+ global $tableSepeActions;
+ global $tableSepeCourseActions;
+ $sql = "SELECT cod, ORIGEN_ACCION,CODIGO_ACCION FROM $tableSepeActions
+ WHERE NOT EXISTS (
+ SELECT * FROM $tableSepeCourseActions WHERE $tableSepeActions.cod = $tableSepeCourseActions.cod_action)
+ ;";
+ $res = Database::query($sql);
+ $aux = array();
+ while ($row = Database::fetch_assoc($res)) {
+ $aux[] = $row;
+ }
+ return $aux;
+}
+
+
+/**
+* function texto_aleatorio (integer $long = 5, boolean $lestras_min = true, boolean $letras_max = true, boolean $num = true))
+*
+* Permite generar contrasenhas de manera aleatoria.
+*
+* @$long: Especifica la longitud de la contrasenha
+* @$letras_min: Podra usar letas en minusculas
+* @$letras_max: Podra usar letas en mayusculas
+* @$num: Podra usar numeros
+*
+* return string
+*/
+
+function texto_aleatorio ($long = 6, $letras_min = true, $letras_max = true, $num = true)
+{
+ $salt = $letras_min?'abchefghknpqrstuvwxyz':'';
+ $salt .= $letras_max?'ACDEFHKNPRSTUVWXYZ':'';
+ $salt .= $num?(strlen($salt)?'2345679':'0123456789'):'';
+
+ if (strlen($salt) == 0) {
+ return '';
+ }
+
+ $i = 0;
+ $str = '';
+
+ srand((double)microtime()*1000000);
+
+ while ($i < $long) {
+ $num = rand(0, strlen($salt)-1);
+ $str .= substr($salt, $num, 1);
+ $i++;
+ }
+
+ return $str;
+}
+
+function info_tutor_rel_profesor($cod)
+{
+ global $tableSepeTutors;
+ $sql = "SELECT * FROM $tableSepeTutors WHERE cod_user_chamilo='".$cod."';";
+ $res = Database::query($sql);
+ $aux = array();
+ if (Database::num_rows($res) > 0) {
+ $row = Database::fetch_assoc($res);
+ } else {
+ $row = false;
+ }
+ return $row;
+}
+
+function info_compentencia_docente($code)
+{
+ $sql = "SELECT * FROM plugin_sepe_competencia_docente WHERE code='".$code."';";
+ $res = Database::query($sql);
+ $row = Database::fetch_assoc($res);
+ return $row['valor'];
+}
+
+function obtener_usuario_chamilo($cod_participant)
+{
+ global $tableSepeParticipants;
+ $sql = "SELECT * FROM $tableSepeParticipants WHERE cod='".$cod_participant."';";
+ $res = Database::query($sql);
+ $row = Database::fetch_assoc($res);
+ if ($row['cod_user_chamilo']=='0' || $row['cod_user_chamilo']=='') {
+ return false;
+ } else {
+ return $row['cod_user_chamilo'];
+ }
+}
+/*
+function obtener_modulos_alumno_accion($user_id, $cod_action)
+{
+ global $tableSepeParticipants;
+ global $tableSepeParticipantsSpecialty;
+ $sql = "SELECT cod FROM $tableSepeParticipants WHERE cod_action='".$cod_action."' AND cod_user_chamilo='".$user_id."';";
+ $res = Database::query($sql);
+ $row = Database::fetch_assoc($res);
+ if ($row['cod']=='' || $row['cod']==0) {
+ return 'No sincronizado con acción formativa';
+ } else {
+ $sql = "SELECT COUNT(*) AS num FROM $tableSepeParticipantsSpecialty WHERE cod_participant='".$row['cod']."';";
+ $res = Database::query($sql);
+ $tmp = Database::fetch_assoc($res);
+ $resultado = $tmp['num'];
+ return $resultado;
+ }
+}
+*/
diff --git a/plugin/sepe/src/sepe_plugin.class.php b/plugin/sepe/src/sepe_plugin.class.php
new file mode 100644
index 0000000000..5f152fdf19
--- /dev/null
+++ b/plugin/sepe/src/sepe_plugin.class.php
@@ -0,0 +1,118 @@
+
+ * @author Julio Montoya
+ */
+class SepePlugin extends Plugin
+{
+ const TABLE_SEPE_CENTER = 'plugin_sepe_center';
+ const TABLE_SEPE_ACTIONS = 'plugin_sepe_actions';
+ const TABLE_SEPE_SPECIALTY = 'plugin_sepe_specialty';
+ const TABLE_SEPE_SPECIALTY_CLASSROOM = 'plugin_sepe_specialty_classroom';
+ const TABLE_SEPE_CENTROS = 'plugin_sepe_centros';
+ const TABLE_SEPE_TUTORS = 'plugin_sepe_tutors';
+ const TABLE_SEPE_SPECIALTY_TUTORS = 'plugin_sepe_specialty_tutors';
+ const TABLE_SEPE_PARTICIPANTS = 'plugin_sepe_participants';
+ const TABLE_SEPE_PARTICIPANTS_SPECIALTY = 'plugin_sepe_participants_specialty';
+ const TABLE_SEPE_PARTICIPANTS_SPECIALTY_TUTORIALS = 'plugin_sepe_participants_specialty_tutorials';
+ const TABLE_SEPE_COURSE_ACTIONS = 'plugin_sepe_course_actions';
+ const TABLE_SEPE_TUTORS_EMPRESA = 'plugin_sepe_tutors_empresa';
+ const TABLE_SEPE_COMPETENCIA_DOCENTE = 'plugin_sepe_competencia_docente';
+ const TABLE_SEPE_LOG_PARTICIPANT = 'plugin_sepe_log_participant';
+ const TABLE_SEPE_LOG_MOD_PARTICIPANT = 'plugin_sepe_log_mod_participant';
+ const TABLE_SEPE_LOG = 'plugin_sepe_log';
+
+ public $isAdminPlugin = true;
+ /**
+ *
+ * @return StaticPlugin
+ */
+ public static function create()
+ {
+ static $result = null;
+ return $result ? $result : $result = new self();
+ }
+
+ protected function __construct()
+ {
+ parent::__construct(
+ '1.0',
+ '
+ Jose Angel Ruiz - NoSoloRed (original author)
+ Julio Montoya (SOAP integration)
+ ',
+ array('sepe_enable' => 'boolean')
+ );
+ }
+
+ /**
+ * This method creates the tables required to this plugin
+ */
+ function install()
+ {
+ $tablesToBeCompared = array(
+ self::TABLE_SEPE_CENTER,
+ self::TABLE_SEPE_ACTIONS,
+ self::TABLE_SEPE_SPECIALTY,
+ self::TABLE_SEPE_SPECIALTY_CLASSROOM,
+ self::TABLE_SEPE_CENTROS,
+ self::TABLE_SEPE_TUTORS,
+ self::TABLE_SEPE_SPECIALTY_TUTORS,
+ self::TABLE_SEPE_PARTICIPANTS,
+ self::TABLE_SEPE_PARTICIPANTS_SPECIALTY,
+ self::TABLE_SEPE_PARTICIPANTS_SPECIALTY_TUTORIALS,
+ self::TABLE_SEPE_COURSE_ACTIONS,
+ self::TABLE_SEPE_TUTORS_EMPRESA,
+ self::TABLE_SEPE_COMPETENCIA_DOCENTE,
+ self::TABLE_SEPE_LOG_PARTICIPANT,
+ self::TABLE_SEPE_LOG_MOD_PARTICIPANT,
+ self::TABLE_SEPE_LOG
+ );
+ $em = Database::getManager();
+ $cn = $em->getConnection();
+ $sm = $cn->getSchemaManager();
+ $tables = $sm->tablesExist($tablesToBeCompared);
+
+ if ($tables) {
+ return false;
+ }
+
+ require_once api_get_path(SYS_PLUGIN_PATH) . 'sepe/database.php';
+ }
+
+ /**
+ * This method drops the plugin tables
+ */
+ function uninstall()
+ {
+ $tablesToBeDeleted = array(
+ self::TABLE_SEPE_CENTER,
+ self::TABLE_SEPE_SPECIALTY_CLASSROOM,
+ self::TABLE_SEPE_CENTROS,
+ self::TABLE_SEPE_TUTORS,
+ self::TABLE_SEPE_SPECIALTY_TUTORS,
+ self::TABLE_SEPE_PARTICIPANTS_SPECIALTY_TUTORIALS,
+ self::TABLE_SEPE_PARTICIPANTS_SPECIALTY,
+ self::TABLE_SEPE_COURSE_ACTIONS,
+ self::TABLE_SEPE_PARTICIPANTS,
+ self::TABLE_SEPE_TUTORS_EMPRESA,
+ self::TABLE_SEPE_SPECIALTY,
+ self::TABLE_SEPE_ACTIONS,
+ self::TABLE_SEPE_COMPETENCIA_DOCENTE,
+ self::TABLE_SEPE_LOG_PARTICIPANT,
+ self::TABLE_SEPE_LOG_MOD_PARTICIPANT,
+ self::TABLE_SEPE_LOG
+ );
+
+ foreach ($tablesToBeDeleted as $tableToBeDeleted) {
+ $table = Database::get_main_table($tableToBeDeleted);
+ $sql = "DROP TABLE IF EXISTS $table";
+ Database::query($sql);
+ }
+ $this->manageTab(false);
+ }
+
+}
diff --git a/plugin/sepe/src/wsse/soap-server-wsse.php b/plugin/sepe/src/wsse/soap-server-wsse.php
new file mode 100644
index 0000000000..346cefdb51
--- /dev/null
+++ b/plugin/sepe/src/wsse/soap-server-wsse.php
@@ -0,0 +1,200 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Robert Richards nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Robert Richards
+ * @copyright 2007 Robert Richards
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version 1.0.0
+ */
+
+require('xmlseclibs.php');
+
+class WSSESoapServer {
+ const WSSENS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
+ const WSSENS_2003 = 'http://schemas.xmlsoap.org/ws/2003/06/secext';
+ const WSUNS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
+ const WSSEPFX = 'wsse';
+ const WSUPFX = 'wsu';
+ private $soapNS, $soapPFX;
+ private $soapDoc = NULL;
+ private $envelope = NULL;
+ private $SOAPXPath = NULL;
+ private $secNode = NULL;
+ public $signAllHeaders = FALSE;
+
+ private function locateSecurityHeader($setActor=NULL) {
+ $wsNamespace = NULL;
+ if ($this->secNode == NULL) {
+ $secnode = NULL;
+ $headers = $this->SOAPXPath->query('//wssoap:Envelope/wssoap:Header');
+ if ($header = $headers->item(0)) {
+ $secnodes = $this->SOAPXPath->query('./*[local-name()="Security"]', $header);
+
+ foreach ($secnodes AS $node) {
+ $nsURI = $node->namespaceURI;
+ if (($nsURI == self::WSSENS) || ($nsURI == self::WSSENS_2003)) {
+ $actor = $node->getAttributeNS($this->soapNS, 'actor');
+ if (empty($actor) || ($actor == $setActor)) {
+ $secnode = $node;
+ $wsNamespace = $nsURI;
+ break;
+ }
+ }
+ }
+ }
+ $this->secNode = $secnode;
+ }
+
+ return $wsNamespace;
+ }
+
+ public function __construct($doc)
+ {
+ $this->soapDoc = $doc;
+ $this->envelope = $doc->documentElement;
+
+ $this->soapNS = $this->envelope->namespaceURI;
+ $this->soapPFX = $this->envelope->prefix;
+
+ $this->SOAPXPath = new DOMXPath($doc);
+ $this->SOAPXPath->registerNamespace('wssoap', $this->soapNS);
+ $this->SOAPXPath->registerNamespace('wswsu', WSSESoapServer::WSUNS);
+ $wsNamespace = $this->locateSecurityHeader();
+ if (!empty($wsNamespace)) {
+ $this->SOAPXPath->registerNamespace('wswsse', $wsNamespace);
+ }
+ }
+
+ public function processSignature($refNode)
+ {
+ $objXMLSecDSig = new XMLSecurityDSig();
+ $objXMLSecDSig->idKeys[] = 'wswsu:Id';
+ $objXMLSecDSig->idNS['wswsu'] = WSSESoapServer::WSUNS;
+ $objXMLSecDSig->sigNode = $refNode;
+
+ /* Canonicalize the signed info */
+ $objXMLSecDSig->canonicalizeSignedInfo();
+ $retVal = $objXMLSecDSig->validateReference();
+
+ if (! $retVal) {
+ throw new Exception("Validation Failed");
+ }
+
+ $key = NULL;
+ $objKey = $objXMLSecDSig->locateKey();
+
+ if ($objKey) {
+ if ($objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $refNode)) {
+ /* Handle any additional key processing such as encrypted keys here */
+ }
+ }
+
+ if (empty($objKey)) {
+ throw new Exception("Error loading key to handle Signature");
+ }
+ do {
+ if (empty($objKey->key)) {
+ $this->SOAPXPath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = "./xmlsecdsig:KeyInfo/wswsse:SecurityTokenReference/wswsse:Reference";
+ $nodeset = $this->SOAPXPath->query($query, $refNode);
+ if ($encmeth = $nodeset->item(0)) {
+ if ($uri = $encmeth->getAttribute("URI")) {
+
+ $arUrl = parse_url($uri);
+
+ if (empty($arUrl['path']) && ($identifier = $arUrl['fragment'])) {
+ $query = '//wswsse:BinarySecurityToken[@wswsu:Id="'.$identifier.'"]';
+ $nodeset = $this->SOAPXPath->query($query);
+ if ($encmeth = $nodeset->item(0)) {
+ $x509cert = $encmeth->textContent;
+ $x509cert = str_replace(array("\r", "\n"), "", $x509cert);
+ $x509cert = "-----BEGIN CERTIFICATE-----\n".chunk_split($x509cert, 64, "\n")."-----END CERTIFICATE-----\n";
+
+ $objKey->loadKey($x509cert);
+ break;
+ }
+ }
+ }
+ }
+ throw new Exception("Error loading key to handle Signature");
+ }
+ } while(0);
+
+ if (! $objXMLSecDSig->verify($objKey)) {
+ throw new Exception("Unable to validate Signature");
+ }
+
+ return true;
+ }
+
+ public function process()
+ {
+ if (empty($this->secNode)) {
+ return;
+ }
+ $node = $this->secNode->firstChild;
+ while ($node) {
+ $nextNode = $node->nextSibling;
+ switch ($node->localName) {
+ case "Signature":
+ if ($this->processSignature($node)) {
+ if ($node->parentNode) {
+ $node->parentNode->removeChild($node);
+ }
+ } else {
+ /* throw fault */
+ return false;
+ }
+ }
+ $node = $nextNode;
+ }
+ $this->secNode->parentNode->removeChild($this->secNode);
+ $this->secNode = NULL;
+
+ return true;
+ }
+
+ public function saveXML()
+ {
+ return $this->soapDoc->saveXML();
+ }
+
+ public function save($file)
+ {
+ return $this->soapDoc->save($file);
+ }
+}
+
diff --git a/plugin/sepe/src/wsse/soap-wsa.php b/plugin/sepe/src/wsse/soap-wsa.php
new file mode 100644
index 0000000000..6bf08eba2a
--- /dev/null
+++ b/plugin/sepe/src/wsse/soap-wsa.php
@@ -0,0 +1,152 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Robert Richards nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Robert Richards
+ * @copyright 2007 Robert Richards
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version 1.0.0
+ */
+
+class WSASoap {
+ const WSANS = 'http://schemas.xmlsoap.org/ws/2004/08/addressing';
+ const WSAPFX = 'wsa';
+ private $soapNS, $soapPFX;
+ private $soapDoc = NULL;
+ private $envelope = NULL;
+ private $SOAPXPath = NULL;
+ private $header = NULL;
+ private $messageID = NULL;
+
+ private function locateHeader() {
+ if ($this->header == NULL) {
+ $headers = $this->SOAPXPath->query('//wssoap:Envelope/wssoap:Header');
+ $header = $headers->item(0);
+ if (! $header) {
+ $header = $this->soapDoc->createElementNS($this->soapNS, $this->soapPFX.':Header');
+ $this->envelope->insertBefore($header, $this->envelope->firstChild);
+ }
+ $this->header = $header;
+ }
+ return $this->header;
+ }
+
+ public function __construct($doc) {
+ $this->soapDoc = $doc;
+ $this->envelope = $doc->documentElement;
+ $this->soapNS = $this->envelope->namespaceURI;
+ $this->soapPFX = $this->envelope->prefix;
+ $this->SOAPXPath = new DOMXPath($doc);
+ $this->SOAPXPath->registerNamespace('wssoap', $this->soapNS);
+ $this->SOAPXPath->registerNamespace('wswsa', WSASoap::WSANS);
+
+ $this->envelope->setAttributeNS("http://www.w3.org/2000/xmlns/", 'xmlns:'.WSASoap::WSAPFX, WSASoap::WSANS);
+ $this->locateHeader();
+ }
+
+ public function addAction($action) {
+ /* Add the WSA Action */
+ $header = $this->locateHeader();
+
+ $nodeAction = $this->soapDoc->createElementNS(WSASoap::WSANS, WSASoap::WSAPFX.':Action', $action);
+ $header->appendChild($nodeAction);
+ }
+
+ public function addTo($location) {
+ /* Add the WSA To */
+ $header = $this->locateHeader();
+
+ $nodeTo = $this->soapDoc->createElementNS(WSASoap::WSANS, WSASoap::WSAPFX.':To', $location);
+ $header->appendChild($nodeTo);
+ }
+
+ private function createID() {
+ $uuid = md5(uniqid(rand(), true));
+ $guid = 'uudi:'.substr($uuid,0,8)."-".
+ substr($uuid,8,4)."-".
+ substr($uuid,12,4)."-".
+ substr($uuid,16,4)."-".
+ substr($uuid,20,12);
+ return $guid;
+ }
+
+ public function addMessageID($id=NULL) {
+ /* Add the WSA MessageID or return existing ID */
+ if (! is_null($this->messageID)) {
+ return $this->messageID;
+ }
+
+ if (empty($id)) {
+ $id = $this->createID();
+ }
+
+ $header = $this->locateHeader();
+
+ $nodeID = $this->soapDoc->createElementNS(WSASoap::WSANS, WSASoap::WSAPFX.':MessageID', $id);
+ $header->appendChild($nodeID);
+ $this->messageID = $id;
+ }
+
+ public function addReplyTo($address = NULL) {
+ /* Create Message ID is not already added - required for ReplyTo */
+ if (is_null($this->messageID)) {
+ $this->addMessageID();
+ }
+ /* Add the WSA ReplyTo */
+ $header = $this->locateHeader();
+
+ $nodeReply = $this->soapDoc->createElementNS(WSASoap::WSANS, WSASoap::WSAPFX.':ReplyTo');
+ $header->appendChild($nodeReply);
+
+ if (empty($address)) {
+ $address = 'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous';
+ }
+ $nodeAddress = $this->soapDoc->createElementNS(WSASoap::WSANS, WSASoap::WSAPFX.':Address', $address);
+ $nodeReply->appendChild($nodeAddress);
+ }
+
+ public function getDoc() {
+ return $this->soapDoc;
+ }
+
+ public function saveXML() {
+ return $this->soapDoc->saveXML();
+ }
+
+ public function save($file) {
+ return $this->soapDoc->save($file);
+ }
+}
+
diff --git a/plugin/sepe/src/wsse/soap-wsse.php b/plugin/sepe/src/wsse/soap-wsse.php
new file mode 100644
index 0000000000..c188c2eec9
--- /dev/null
+++ b/plugin/sepe/src/wsse/soap-wsse.php
@@ -0,0 +1,497 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Robert Richards nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Robert Richards
+ * @copyright 2007-2010 Robert Richards
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version 1.1.0-dev
+ */
+
+require('xmlseclibs.php');
+
+class WSSESoap {
+ const WSSENS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
+ const WSUNS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
+ const WSUNAME = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0';
+ const WSSEPFX = 'wsse';
+ const WSUPFX = 'wsu';
+ private $soapNS, $soapPFX;
+ private $soapDoc = NULL;
+ private $envelope = NULL;
+ private $SOAPXPath = NULL;
+ private $secNode = NULL;
+ public $signAllHeaders = FALSE;
+
+ private function locateSecurityHeader($bMustUnderstand = TRUE, $setActor = NULL) {
+ if ($this->secNode == NULL) {
+ $headers = $this->SOAPXPath->query('//wssoap:Envelope/wssoap:Header');
+ $header = $headers->item(0);
+ if (! $header) {
+ $header = $this->soapDoc->createElementNS($this->soapNS, $this->soapPFX.':Header');
+ $this->envelope->insertBefore($header, $this->envelope->firstChild);
+ }
+ $secnodes = $this->SOAPXPath->query('./wswsse:Security', $header);
+ $secnode = NULL;
+ foreach ($secnodes AS $node) {
+ $actor = $node->getAttributeNS($this->soapNS, 'actor');
+ if ($actor == $setActor) {
+ $secnode = $node;
+ break;
+ }
+ }
+ if (! $secnode) {
+ $secnode = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':Security');
+ ///if (isset($secnode) && !empty($secnode)) {
+ $header->appendChild($secnode);
+ //}
+ if ($bMustUnderstand) {
+ $secnode->setAttributeNS($this->soapNS, $this->soapPFX.':mustUnderstand', '1');
+ }
+ if (! empty($setActor)) {
+ $ename = 'actor';
+ if ($this->soapNS == 'http://www.w3.org/2003/05/soap-envelope') {
+ $ename = 'role';
+ }
+ $secnode->setAttributeNS($this->soapNS, $this->soapPFX.':'.$ename, $setActor);
+ }
+ }
+ $this->secNode = $secnode;
+ }
+ return $this->secNode;
+ }
+
+ public function __construct($doc, $bMustUnderstand = TRUE, $setActor=NULL) {
+ $this->soapDoc = $doc;
+ $this->envelope = $doc->documentElement;
+ $this->soapNS = $this->envelope->namespaceURI;
+ $this->soapPFX = $this->envelope->prefix;
+ $this->SOAPXPath = new DOMXPath($doc);
+ $this->SOAPXPath->registerNamespace('wssoap', $this->soapNS);
+ $this->SOAPXPath->registerNamespace('wswsse', WSSESoap::WSSENS);
+ $this->locateSecurityHeader($bMustUnderstand, $setActor);
+ }
+
+ public function addTimestamp($secondsToExpire=3600) {
+ /* Add the WSU timestamps */
+ $security = $this->locateSecurityHeader();
+
+ $timestamp = $this->soapDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX.':Timestamp');
+ $security->insertBefore($timestamp, $security->firstChild);
+ $currentTime = time();
+ $created = $this->soapDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX.':Created', gmdate("Y-m-d\TH:i:s", $currentTime).'Z');
+ $timestamp->appendChild($created);
+ if (! is_null($secondsToExpire)) {
+ $expire = $this->soapDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX.':Expires', gmdate("Y-m-d\TH:i:s", $currentTime + $secondsToExpire).'Z');
+ $timestamp->appendChild($expire);
+ }
+ }
+
+ public function addUserToken($userName, $password=NULL, $passwordDigest=FALSE) {
+ if ($passwordDigest && empty($password)) {
+ throw new Exception("Cannot calculate the digest without a password");
+ }
+
+ $security = $this->locateSecurityHeader();
+
+ $token = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':UsernameToken');
+ $security->insertBefore($token, $security->firstChild);
+
+ $username = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':Username', $userName);
+ $token->appendChild($username);
+
+ /* Generate nonce - create a 256 bit session key to be used */
+ $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
+ $nonce = $objKey->generateSessionKey();
+ unset($objKey);
+ $createdate = gmdate("Y-m-d\TH:i:s").'Z';
+
+ if ($password) {
+ $passType = WSSESoap::WSUNAME.'#PasswordText';
+ if ($passwordDigest) {
+ $password = base64_encode(sha1($nonce.$createdate. $password, true));
+ $passType = WSSESoap::WSUNAME.'#PasswordDigest';
+ }
+ $passwordNode = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':Password', $password);
+ $token->appendChild($passwordNode);
+ $passwordNode->setAttribute('Type', $passType);
+ }
+
+ $nonceNode = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':Nonce', base64_encode($nonce));
+ $token->appendChild($nonceNode);
+
+ $created = $this->soapDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX.':Created', $createdate);
+ $token->appendChild($created);
+ }
+
+ public function addBinaryToken($cert, $isPEMFormat=TRUE, $isDSig=TRUE) {
+ $security = $this->locateSecurityHeader();
+ $data = XMLSecurityDSig::get509XCert($cert, $isPEMFormat);
+
+ $token = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':BinarySecurityToken', $data);
+ $security->insertBefore($token, $security->firstChild);
+
+ $token->setAttribute('EncodingType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary');
+ $token->setAttributeNS(WSSESoap::WSUNS, WSSESoap::WSUPFX.':Id', XMLSecurityDSig::generate_GUID());
+ $token->setAttribute('ValueType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3');
+
+ return $token;
+ }
+
+ public function attachTokentoSig($token) {
+ if (! ($token instanceof DOMElement)) {
+ throw new Exception('Invalid parameter: BinarySecurityToken element expected');
+ }
+ $objXMLSecDSig = new XMLSecurityDSig();
+ if ($objDSig = $objXMLSecDSig->locateSignature($this->soapDoc)) {
+ $tokenURI = '#'.$token->getAttributeNS(WSSESoap::WSUNS, "Id");
+ $this->SOAPXPath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = "./secdsig:KeyInfo";
+ $nodeset = $this->SOAPXPath->query($query, $objDSig);
+ $keyInfo = $nodeset->item(0);
+ if (! $keyInfo) {
+ $keyInfo = $objXMLSecDSig->createNewSignNode('KeyInfo');
+ $objDSig->appendChild($keyInfo);
+ }
+
+ $tokenRef = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':SecurityTokenReference');
+ $keyInfo->appendChild($tokenRef);
+ $reference = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':Reference');
+ $reference->setAttribute("URI", $tokenURI);
+ $tokenRef->appendChild($reference);
+ } else {
+ throw new Exception('Unable to locate digital signature');
+ }
+ }
+
+ public function signSoapDoc($objKey, $options = NULL) {
+ $objDSig = new XMLSecurityDSig();
+
+ $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
+
+ $arNodes = array();
+ foreach ($this->secNode->childNodes AS $node) {
+ if ($node->nodeType == XML_ELEMENT_NODE) {
+ $arNodes[] = $node;
+ }
+ }
+
+ if ($this->signAllHeaders) {
+ foreach ($this->secNode->parentNode->childNodes AS $node) {
+ if (($node->nodeType == XML_ELEMENT_NODE) &&
+ ($node->namespaceURI != WSSESoap::WSSENS)) {
+ $arNodes[] = $node;
+ }
+ }
+ }
+
+ foreach ($this->envelope->childNodes AS $node) {
+ if ($node->namespaceURI == $this->soapNS && $node->localName == 'Body') {
+ $arNodes[] = $node;
+ break;
+ }
+ }
+
+ $algorithm = XMLSecurityDSig::SHA1;
+ if (is_array($options) && isset($options["algorithm"])) {
+ $algorithm = $options["algorithm"];
+ }
+
+ $arOptions = array('prefix'=>WSSESoap::WSUPFX, 'prefix_ns'=>WSSESoap::WSUNS);
+ $objDSig->addReferenceList($arNodes, $algorithm, NULL, $arOptions);
+
+ $objDSig->sign($objKey);
+
+ $insertTop = TRUE;
+ if (is_array($options) && isset($options["insertBefore"])) {
+ $insertTop = (bool)$options["insertBefore"];
+ }
+ $objDSig->appendSignature($this->secNode, $insertTop);
+
+/* New suff */
+
+ if (is_array($options)) {
+ if (! empty($options["KeyInfo"]) ) {
+ if (! empty($options["KeyInfo"]["X509SubjectKeyIdentifier"])) {
+ $sigNode = $this->secNode->firstChild->nextSibling;
+ $objDoc = $sigNode->ownerDocument;
+ $keyInfo = $sigNode->ownerDocument->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:KeyInfo');
+ $sigNode->appendChild($keyInfo);
+ $tokenRef = $objDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':SecurityTokenReference');
+ $keyInfo->appendChild($tokenRef);
+ $reference = $objDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':KeyIdentifier');
+ $reference->setAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier");
+ $reference->setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
+ $tokenRef->appendChild($reference);
+ $x509 = openssl_x509_parse($objKey->getX509Certificate());
+ $keyid = $x509["extensions"]["subjectKeyIdentifier"];
+ $arkeyid = split(":", $keyid);
+
+ $data = "";
+ foreach ($arkeyid AS $hexchar) {
+ $data .= chr(hexdec($hexchar));
+ }
+ $dataNode = new DOMText(base64_encode($data));
+ $reference->appendChild($dataNode);
+ }
+ }
+ }
+ }
+
+ public function addEncryptedKey($node, $key, $token, $options = NULL) {
+ if (! $key->encKey) {
+ return FALSE;
+ }
+ $encKey = $key->encKey;
+ $security = $this->locateSecurityHeader();
+ $doc = $security->ownerDocument;
+ if (! $doc->isSameNode($encKey->ownerDocument)) {
+ $key->encKey = $security->ownerDocument->importNode($encKey, TRUE);
+ $encKey = $key->encKey;
+ }
+ if (! empty($key->guid)) {
+ return TRUE;
+ }
+
+ $lastToken = NULL;
+ $findTokens = $security->firstChild;
+ while ($findTokens) {
+ if ($findTokens->localName == 'BinarySecurityToken') {
+ $lastToken = $findTokens;
+ }
+ $findTokens = $findTokens->nextSibling;
+ }
+ if ($lastToken) {
+ $lastToken = $lastToken->nextSibling;
+ }
+
+ $security->insertBefore($encKey, $lastToken);
+ $key->guid = XMLSecurityDSig::generate_GUID();
+ $encKey->setAttribute('Id', $key->guid);
+ $encMethod = $encKey->firstChild;
+ while ($encMethod && $encMethod->localName != 'EncryptionMethod') {
+ $encMethod = $encMethod->nextChild;
+ }
+ if ($encMethod) {
+ $encMethod = $encMethod->nextSibling;
+ }
+ $objDoc = $encKey->ownerDocument;
+ $keyInfo = $objDoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyInfo');
+ $encKey->insertBefore($keyInfo, $encMethod);
+ $tokenRef = $objDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':SecurityTokenReference');
+ $keyInfo->appendChild($tokenRef);
+/* New suff */
+ if (is_array($options)) {
+ if (! empty($options["KeyInfo"]) ) {
+ if (! empty($options["KeyInfo"]["X509SubjectKeyIdentifier"])) {
+ $reference = $objDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':KeyIdentifier');
+ $reference->setAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier");
+ $reference->setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
+ $tokenRef->appendChild($reference);
+ $x509 = openssl_x509_parse($token->getX509Certificate());
+ $keyid = $x509["extensions"]["subjectKeyIdentifier"];
+ $arkeyid = split(":", $keyid);
+ $data = "";
+ foreach ($arkeyid AS $hexchar) {
+ $data .= chr(hexdec($hexchar));
+ }
+ $dataNode = new DOMText(base64_encode($data));
+ $reference->appendChild($dataNode);
+ return TRUE;
+ }
+ }
+ }
+
+ $tokenURI = '#'.$token->getAttributeNS(WSSESoap::WSUNS, "Id");
+ $reference = $objDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX.':Reference');
+ $reference->setAttribute("URI", $tokenURI);
+ $tokenRef->appendChild($reference);
+
+ return TRUE;
+ }
+
+ public function AddReference($baseNode, $guid) {
+ $refList = NULL;
+ $child = $baseNode->firstChild;
+ while($child) {
+ if (($child->namespaceURI == XMLSecEnc::XMLENCNS) && ($child->localName == 'ReferenceList')) {
+ $refList = $child;
+ break;
+ }
+ $child = $child->nextSibling;
+ }
+ $doc = $baseNode->ownerDocument;
+ if (is_null($refList)) {
+ $refList = $doc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:ReferenceList');
+ $baseNode->appendChild($refList);
+ }
+ $dataref = $doc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:DataReference');
+ $refList->appendChild($dataref);
+ $dataref->setAttribute('URI', '#'.$guid);
+ }
+
+ public function EncryptBody($siteKey, $objKey, $token) {
+
+ $enc = new XMLSecEnc();
+ foreach ($this->envelope->childNodes AS $node) {
+ if ($node->namespaceURI == $this->soapNS && $node->localName == 'Body') {
+ break;
+ }
+ }
+ $enc->setNode($node);
+ /* encrypt the symmetric key */
+ $enc->encryptKey($siteKey, $objKey, FALSE);
+
+ $enc->type = XMLSecEnc::Content;
+ /* Using the symmetric key to actually encrypt the data */
+ $encNode = $enc->encryptNode($objKey);
+
+ $guid = XMLSecurityDSig::generate_GUID();
+ $encNode->setAttribute('Id', $guid);
+
+ $refNode = $encNode->firstChild;
+ while($refNode && $refNode->nodeType != XML_ELEMENT_NODE) {
+ $refNode = $refNode->nextSibling;
+ }
+ if ($refNode) {
+ $refNode = $refNode->nextSibling;
+ }
+ if ($this->addEncryptedKey($encNode, $enc, $token)) {
+ $this->AddReference($enc->encKey, $guid);
+ }
+ }
+
+ public function encryptSoapDoc($siteKey, $objKey, $options=NULL, $encryptSignature=TRUE) {
+
+ $enc = new XMLSecEnc();
+
+ $xpath = new DOMXPath($this->envelope->ownerDocument);
+ if ($encryptSignature == FALSE) {
+ $nodes = $xpath->query('//*[local-name()="Body"]');
+ } else {
+ $nodes = $xpath->query('//*[local-name()="Signature"] | //*[local-name()="Body"]');
+ }
+
+ foreach ($nodes AS $node) {
+ $type = XMLSecEnc::Element;
+ $name = $node->localName;
+ if ($name == "Body") {
+ $type = XMLSecEnc::Content;
+ }
+ $enc->addReference($name, $node, $type);
+ }
+
+ $enc->encryptReferences($objKey);
+
+ $enc->encryptKey($siteKey, $objKey, false);
+
+ $nodes = $xpath->query('//*[local-name()="Security"]');
+ $signode = $nodes->item(0);
+ $this->addEncryptedKey($signode, $enc, $siteKey, $options);
+ }
+
+ public function decryptSoapDoc($doc, $options) {
+
+ $privKey = NULL;
+ $privKey_isFile = FALSE;
+ $privKey_isCert = FALSE;
+
+ if (is_array($options)) {
+ $privKey = (! empty($options["keys"]["private"]["key"]) ? $options["keys"]["private"]["key"] : NULL);
+ $privKey_isFile = (! empty($options["keys"]["private"]["isFile"]) ? TRUE : FALSE);
+ $privKey_isCert = (! empty($options["keys"]["private"]["isCert"]) ? TRUE : FALSE);
+ }
+
+ $objenc = new XMLSecEnc();
+
+ $xpath = new DOMXPath($doc);
+ $envns = $doc->documentElement->namespaceURI;
+ $xpath->registerNamespace("soapns", $envns);
+ $xpath->registerNamespace("soapenc", "http://www.w3.org/2001/04/xmlenc#");
+
+ $nodes = $xpath->query('/soapns:Envelope/soapns:Header/*[local-name()="Security"]/soapenc:EncryptedKey');
+
+ $references = array();
+ if ($node = $nodes->item(0)) {
+ $objenc = new XMLSecEnc();
+ $objenc->setNode($node);
+ if (! $objKey = $objenc->locateKey()) {
+ throw new Exception("Unable to locate algorithm for this Encrypted Key");
+ }
+ $objKey->isEncrypted = TRUE;
+ $objKey->encryptedCtx = $objenc;
+ XMLSecEnc::staticLocateKeyInfo($objKey, $node);
+ if ($objKey && $objKey->isEncrypted) {
+ $objencKey = $objKey->encryptedCtx;
+ $objKey->loadKey($privKey, $privKey_isFile, $privKey_isCert);
+ $key = $objencKey->decryptKey($objKey);
+ $objKey->loadKey($key);
+ }
+
+ $refnodes = $xpath->query('./soapenc:ReferenceList/soapenc:DataReference/@URI', $node);
+ foreach ($refnodes as $reference) {
+ $references[] = $reference->nodeValue;
+ }
+ }
+
+ foreach ($references AS $reference) {
+ $arUrl = parse_url($reference);
+ $reference = $arUrl['fragment'];
+ $query = '//*[@Id="'.$reference.'"]';
+ $nodes = $xpath->query($query);
+ $encData = $nodes->item(0);
+
+ if ($algo = $xpath->evaluate("string(./soapenc:EncryptionMethod/@Algorithm)", $encData)) {
+ $objKey = new XMLSecurityKey($algo);
+ $objKey->loadKey($key);
+ }
+
+ $objenc->setNode($encData);
+ $objenc->type = $encData->getAttribute("Type");
+ $decrypt = $objenc->decryptNode($objKey, TRUE);
+ }
+
+ return TRUE;
+ }
+
+ public function saveXML() {
+ return $this->soapDoc->saveXML();
+ }
+
+ public function save($file) {
+ return $this->soapDoc->save($file);
+ }
+}
+
diff --git a/plugin/sepe/src/wsse/xmlseclibs.php b/plugin/sepe/src/wsse/xmlseclibs.php
new file mode 100644
index 0000000000..41f304b8d0
--- /dev/null
+++ b/plugin/sepe/src/wsse/xmlseclibs.php
@@ -0,0 +1,1817 @@
+.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Robert Richards nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Robert Richards
+ * @copyright 2007-2013 Robert Richards
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version 1.3.1
+ */
+
+/*
+Functions to generate simple cases of Exclusive Canonical XML - Callable function is C14NGeneral()
+i.e.: $canonical = C14NGeneral($domelement, TRUE);
+*/
+
+/* helper function */
+function sortAndAddAttrs($element, $arAtts) {
+ $newAtts = array();
+ foreach ($arAtts AS $attnode) {
+ $newAtts[$attnode->nodeName] = $attnode;
+ }
+ ksort($newAtts);
+ foreach ($newAtts as $attnode) {
+ $element->setAttribute($attnode->nodeName, $attnode->nodeValue);
+ }
+}
+
+/* helper function */
+function canonical($tree, $element, $withcomments) {
+ if ($tree->nodeType != XML_DOCUMENT_NODE) {
+ $dom = $tree->ownerDocument;
+ } else {
+ $dom = $tree;
+ }
+ if ($element->nodeType != XML_ELEMENT_NODE) {
+ if ($element->nodeType == XML_DOCUMENT_NODE) {
+ foreach ($element->childNodes AS $node) {
+ canonical($dom, $node, $withcomments);
+ }
+ return;
+ }
+ if ($element->nodeType == XML_COMMENT_NODE && ! $withcomments) {
+ return;
+ }
+ $tree->appendChild($dom->importNode($element, TRUE));
+ return;
+ }
+ $arNS = array();
+ if ($element->namespaceURI != "") {
+ if ($element->prefix == "") {
+ $elCopy = $dom->createElementNS($element->namespaceURI, $element->nodeName);
+ } else {
+ $prefix = $tree->lookupPrefix($element->namespaceURI);
+ if ($prefix == $element->prefix) {
+ $elCopy = $dom->createElementNS($element->namespaceURI, $element->nodeName);
+ } else {
+ $elCopy = $dom->createElement($element->nodeName);
+ $arNS[$element->namespaceURI] = $element->prefix;
+ }
+ }
+ } else {
+ $elCopy = $dom->createElement($element->nodeName);
+ }
+ $tree->appendChild($elCopy);
+
+ /* Create DOMXPath based on original document */
+ $xPath = new DOMXPath($element->ownerDocument);
+
+ /* Get namespaced attributes */
+ $arAtts = $xPath->query('attribute::*[namespace-uri(.) != ""]', $element);
+
+ /* Create an array with namespace URIs as keys, and sort them */
+ foreach ($arAtts AS $attnode) {
+ if (array_key_exists($attnode->namespaceURI, $arNS) &&
+ ($arNS[$attnode->namespaceURI] == $attnode->prefix)) {
+ continue;
+ }
+ $prefix = $tree->lookupPrefix($attnode->namespaceURI);
+ if ($prefix != $attnode->prefix) {
+ $arNS[$attnode->namespaceURI] = $attnode->prefix;
+ } else {
+ $arNS[$attnode->namespaceURI] = NULL;
+ }
+ }
+ if (count($arNS) > 0) {
+ asort($arNS);
+ }
+
+ /* Add namespace nodes */
+ foreach ($arNS AS $namespaceURI=>$prefix) {
+ if ($prefix != NULL) {
+ $elCopy->setAttributeNS("http://www.w3.org/2000/xmlns/",
+ "xmlns:".$prefix, $namespaceURI);
+ }
+ }
+ if (count($arNS) > 0) {
+ ksort($arNS);
+ }
+
+ /* Get attributes not in a namespace, and then sort and add them */
+ $arAtts = $xPath->query('attribute::*[namespace-uri(.) = ""]', $element);
+ sortAndAddAttrs($elCopy, $arAtts);
+
+ /* Loop through the URIs, and then sort and add attributes within that namespace */
+ foreach ($arNS as $nsURI=>$prefix) {
+ $arAtts = $xPath->query('attribute::*[namespace-uri(.) = "'.$nsURI.'"]', $element);
+ sortAndAddAttrs($elCopy, $arAtts);
+ }
+
+ foreach ($element->childNodes AS $node) {
+ canonical($elCopy, $node, $withcomments);
+ }
+}
+
+/*
+$element - DOMElement for which to produce the canonical version of
+$exclusive - boolean to indicate exclusive canonicalization (must pass TRUE)
+$withcomments - boolean indicating wether or not to include comments in canonicalized form
+*/
+function C14NGeneral($element, $exclusive=FALSE, $withcomments=FALSE) {
+ /* IF PHP 5.2+ then use built in canonical functionality */
+ $php_version = explode('.', PHP_VERSION);
+ if (($php_version[0] > 5) || ($php_version[0] == 5 && $php_version[1] >= 2) ) {
+ return $element->C14N($exclusive, $withcomments);
+ }
+
+ /* Must be element or document */
+ if (! $element instanceof DOMElement && ! $element instanceof DOMDocument) {
+ return NULL;
+ }
+ /* Currently only exclusive XML is supported */
+ if ($exclusive == FALSE) {
+ throw new Exception("Only exclusive canonicalization is supported in this version of PHP");
+ }
+
+ $copyDoc = new DOMDocument();
+ canonical($copyDoc, $element, $withcomments);
+ return $copyDoc->saveXML($copyDoc->documentElement, LIBXML_NOEMPTYTAG);
+}
+
+class XMLSecurityKey {
+ const TRIPLEDES_CBC = 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc';
+ const AES128_CBC = 'http://www.w3.org/2001/04/xmlenc#aes128-cbc';
+ const AES192_CBC = 'http://www.w3.org/2001/04/xmlenc#aes192-cbc';
+ const AES256_CBC = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc';
+ const RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5';
+ const RSA_OAEP_MGF1P = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p';
+ const DSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1';
+ const RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
+ const RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
+ const RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
+ const RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
+
+ private $cryptParams = array();
+ public $type = 0;
+ public $key = NULL;
+ public $passphrase = "";
+ public $iv = NULL;
+ public $name = NULL;
+ public $keyChain = NULL;
+ public $isEncrypted = FALSE;
+ public $encryptedCtx = NULL;
+ public $guid = NULL;
+
+ /**
+ * This variable contains the certificate as a string if this key represents an X509-certificate.
+ * If this key doesn't represent a certificate, this will be NULL.
+ */
+ private $x509Certificate = NULL;
+
+ /* This variable contains the certificate thunbprint if we have loaded an X509-certificate. */
+ private $X509Thumbprint = NULL;
+
+ public function __construct($type, $params=NULL) {
+ srand();
+ switch ($type) {
+ case (XMLSecurityKey::TRIPLEDES_CBC):
+ $this->cryptParams['library'] = 'mcrypt';
+ $this->cryptParams['cipher'] = MCRYPT_TRIPLEDES;
+ $this->cryptParams['mode'] = MCRYPT_MODE_CBC;
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc';
+ $this->cryptParams['keysize'] = 24;
+ break;
+ case (XMLSecurityKey::AES128_CBC):
+ $this->cryptParams['library'] = 'mcrypt';
+ $this->cryptParams['cipher'] = MCRYPT_RIJNDAEL_128;
+ $this->cryptParams['mode'] = MCRYPT_MODE_CBC;
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#aes128-cbc';
+ $this->cryptParams['keysize'] = 16;
+ break;
+ case (XMLSecurityKey::AES192_CBC):
+ $this->cryptParams['library'] = 'mcrypt';
+ $this->cryptParams['cipher'] = MCRYPT_RIJNDAEL_128;
+ $this->cryptParams['mode'] = MCRYPT_MODE_CBC;
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#aes192-cbc';
+ $this->cryptParams['keysize'] = 24;
+ break;
+ case (XMLSecurityKey::AES256_CBC):
+ $this->cryptParams['library'] = 'mcrypt';
+ $this->cryptParams['cipher'] = MCRYPT_RIJNDAEL_128;
+ $this->cryptParams['mode'] = MCRYPT_MODE_CBC;
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc';
+ $this->cryptParams['keysize'] = 32;
+ break;
+ case (XMLSecurityKey::RSA_1_5):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5';
+ if (is_array($params) && ! empty($params['type'])) {
+ if ($params['type'] == 'public' || $params['type'] == 'private') {
+ $this->cryptParams['type'] = $params['type'];
+ break;
+ }
+ }
+ throw new Exception('Certificate "type" (private/public) must be passed via parameters');
+ return;
+ case (XMLSecurityKey::RSA_OAEP_MGF1P):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['padding'] = OPENSSL_PKCS1_OAEP_PADDING;
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p';
+ $this->cryptParams['hash'] = NULL;
+ if (is_array($params) && ! empty($params['type'])) {
+ if ($params['type'] == 'public' || $params['type'] == 'private') {
+ $this->cryptParams['type'] = $params['type'];
+ break;
+ }
+ }
+ throw new Exception('Certificate "type" (private/public) must be passed via parameters');
+ return;
+ case (XMLSecurityKey::RSA_SHA1):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['method'] = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
+ $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+ if (is_array($params) && ! empty($params['type'])) {
+ if ($params['type'] == 'public' || $params['type'] == 'private') {
+ $this->cryptParams['type'] = $params['type'];
+ break;
+ }
+ }
+ throw new Exception('Certificate "type" (private/public) must be passed via parameters');
+ break;
+ case (XMLSecurityKey::RSA_SHA256):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
+ $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+ $this->cryptParams['digest'] = 'SHA256';
+ if (is_array($params) && ! empty($params['type'])) {
+ if ($params['type'] == 'public' || $params['type'] == 'private') {
+ $this->cryptParams['type'] = $params['type'];
+ break;
+ }
+ }
+ throw new Exception('Certificate "type" (private/public) must be passed via parameters');
+ break;
+ case (XMLSecurityKey::RSA_SHA384):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
+ $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+ $this->cryptParams['digest'] = 'SHA384';
+ if (is_array($params) && ! empty($params['type'])) {
+ if ($params['type'] == 'public' || $params['type'] == 'private') {
+ $this->cryptParams['type'] = $params['type'];
+ break;
+ }
+ }
+ case (XMLSecurityKey::RSA_SHA512):
+ $this->cryptParams['library'] = 'openssl';
+ $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
+ $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+ $this->cryptParams['digest'] = 'SHA512';
+ if (is_array($params) && ! empty($params['type'])) {
+ if ($params['type'] == 'public' || $params['type'] == 'private') {
+ $this->cryptParams['type'] = $params['type'];
+ break;
+ }
+ }
+ default:
+ throw new Exception('Invalid Key Type');
+ return;
+ }
+ $this->type = $type;
+ }
+
+ /**
+ * Retrieve the key size for the symmetric encryption algorithm..
+ *
+ * If the key size is unknown, or this isn't a symmetric encryption algorithm,
+ * NULL is returned.
+ *
+ * @return int|NULL The number of bytes in the key.
+ */
+ public function getSymmetricKeySize() {
+ if (! isset($this->cryptParams['keysize'])) {
+ return NULL;
+ }
+ return $this->cryptParams['keysize'];
+ }
+
+ public function generateSessionKey() {
+ if (!isset($this->cryptParams['keysize'])) {
+ throw new Exception('Unknown key size for type "' . $this->type . '".');
+ }
+ $keysize = $this->cryptParams['keysize'];
+
+ if (function_exists('openssl_random_pseudo_bytes')) {
+ /* We have PHP >= 5.3 - use openssl to generate session key. */
+ $key = openssl_random_pseudo_bytes($keysize);
+ } else {
+ /* Generating random key using iv generation routines */
+ $key = mcrypt_create_iv($keysize, MCRYPT_RAND);
+ }
+
+ if ($this->type === XMLSecurityKey::TRIPLEDES_CBC) {
+ /* Make sure that the generated key has the proper parity bits set.
+ * Mcrypt doesn't care about the parity bits, but others may care.
+ */
+ for ($i = 0; $i < strlen($key); $i++) {
+ $byte = ord($key[$i]) & 0xfe;
+ $parity = 1;
+ for ($j = 1; $j < 8; $j++) {
+ $parity ^= ($byte >> $j) & 1;
+ }
+ $byte |= $parity;
+ $key[$i] = chr($byte);
+ }
+ }
+
+ $this->key = $key;
+ return $key;
+ }
+
+ public static function getRawThumbprint($cert) {
+
+ $arCert = explode("\n", $cert);
+ $data = '';
+ $inData = FALSE;
+
+ foreach ($arCert AS $curData) {
+ if (! $inData) {
+ if (strncmp($curData, '-----BEGIN CERTIFICATE', 22) == 0) {
+ $inData = TRUE;
+ }
+ } else {
+ if (strncmp($curData, '-----END CERTIFICATE', 20) == 0) {
+ $inData = FALSE;
+ break;
+ }
+ $data .= trim($curData);
+ }
+ }
+
+ if (! empty($data)) {
+ return strtolower(sha1(base64_decode($data)));
+ }
+
+ return NULL;
+ }
+
+ public function loadKey($key, $isFile=FALSE, $isCert = FALSE) {
+ if ($isFile) {
+ $this->key = file_get_contents($key);
+ } else {
+ $this->key = $key;
+ }
+ if ($isCert) {
+ $this->key = openssl_x509_read($this->key);
+ openssl_x509_export($this->key, $str_cert);
+ $this->x509Certificate = $str_cert;
+ $this->key = $str_cert;
+ } else {
+ $this->x509Certificate = NULL;
+ }
+ if ($this->cryptParams['library'] == 'openssl') {
+ if ($this->cryptParams['type'] == 'public') {
+ if ($isCert) {
+ /* Load the thumbprint if this is an X509 certificate. */
+ $this->X509Thumbprint = self::getRawThumbprint($this->key);
+ }
+ $this->key = openssl_get_publickey($this->key);
+
+ } else {
+ $this->key = openssl_get_privatekey($this->key, $this->passphrase);
+ }
+ } else if ($this->cryptParams['cipher'] == MCRYPT_RIJNDAEL_128) {
+ /* Check key length */
+ switch ($this->type) {
+ case (XMLSecurityKey::AES256_CBC):
+ if (strlen($this->key) < 25) {
+ throw new Exception('Key must contain at least 25 characters for this cipher');
+ }
+ break;
+ case (XMLSecurityKey::AES192_CBC):
+ if (strlen($this->key) < 17) {
+ throw new Exception('Key must contain at least 17 characters for this cipher');
+ }
+ break;
+ }
+ }
+ }
+
+ private function encryptMcrypt($data) {
+ $td = mcrypt_module_open($this->cryptParams['cipher'], '', $this->cryptParams['mode'], '');
+ $this->iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
+ mcrypt_generic_init($td, $this->key, $this->iv);
+ if ($this->cryptParams['mode'] == MCRYPT_MODE_CBC) {
+ $bs = mcrypt_enc_get_block_size($td);
+ for ($datalen0=$datalen=strlen($data); (($datalen%$bs)!=($bs-1)); $datalen++)
+ $data.=chr(rand(1, 127));
+ $data.=chr($datalen-$datalen0+1);
+ }
+ $encrypted_data = $this->iv.mcrypt_generic($td, $data);
+ mcrypt_generic_deinit($td);
+ mcrypt_module_close($td);
+ return $encrypted_data;
+ }
+
+ private function decryptMcrypt($data) {
+ $td = mcrypt_module_open($this->cryptParams['cipher'], '', $this->cryptParams['mode'], '');
+ $iv_length = mcrypt_enc_get_iv_size($td);
+
+ $this->iv = substr($data, 0, $iv_length);
+ $data = substr($data, $iv_length);
+
+ mcrypt_generic_init($td, $this->key, $this->iv);
+ $decrypted_data = mdecrypt_generic($td, $data);
+ mcrypt_generic_deinit($td);
+ mcrypt_module_close($td);
+ if ($this->cryptParams['mode'] == MCRYPT_MODE_CBC) {
+ $dataLen = strlen($decrypted_data);
+ $paddingLength = substr($decrypted_data, $dataLen - 1, 1);
+ $decrypted_data = substr($decrypted_data, 0, $dataLen - ord($paddingLength));
+ }
+ return $decrypted_data;
+ }
+
+ private function encryptOpenSSL($data) {
+ if ($this->cryptParams['type'] == 'public') {
+ if (! openssl_public_encrypt($data, $encrypted_data, $this->key, $this->cryptParams['padding'])) {
+ throw new Exception('Failure encrypting Data');
+ return;
+ }
+ } else {
+ if (! openssl_private_encrypt($data, $encrypted_data, $this->key, $this->cryptParams['padding'])) {
+ throw new Exception('Failure encrypting Data');
+ return;
+ }
+ }
+ return $encrypted_data;
+ }
+
+ private function decryptOpenSSL($data) {
+ if ($this->cryptParams['type'] == 'public') {
+ if (! openssl_public_decrypt($data, $decrypted, $this->key, $this->cryptParams['padding'])) {
+ throw new Exception('Failure decrypting Data');
+ return;
+ }
+ } else {
+ if (! openssl_private_decrypt($data, $decrypted, $this->key, $this->cryptParams['padding'])) {
+ throw new Exception('Failure decrypting Data');
+ return;
+ }
+ }
+ return $decrypted;
+ }
+
+ private function signOpenSSL($data) {
+ $algo = OPENSSL_ALGO_SHA1;
+ if (! empty($this->cryptParams['digest'])) {
+ $algo = $this->cryptParams['digest'];
+ }
+
+ if (! openssl_sign ($data, $signature, $this->key, $algo)) {
+ throw new Exception('Failure Signing Data: ' . openssl_error_string() . ' - ' . $algo);
+ return;
+ }
+ return $signature;
+ }
+
+ private function verifyOpenSSL($data, $signature) {
+ $algo = OPENSSL_ALGO_SHA1;
+ if (! empty($this->cryptParams['digest'])) {
+ $algo = $this->cryptParams['digest'];
+ }
+ return openssl_verify ($data, $signature, $this->key, $algo);
+ }
+
+ public function encryptData($data) {
+ switch ($this->cryptParams['library']) {
+ case 'mcrypt':
+ return $this->encryptMcrypt($data);
+ break;
+ case 'openssl':
+ return $this->encryptOpenSSL($data);
+ break;
+ }
+ }
+
+ public function decryptData($data) {
+ switch ($this->cryptParams['library']) {
+ case 'mcrypt':
+ return $this->decryptMcrypt($data);
+ break;
+ case 'openssl':
+ return $this->decryptOpenSSL($data);
+ break;
+ }
+ }
+
+ public function signData($data) {
+ switch ($this->cryptParams['library']) {
+ case 'openssl':
+ return $this->signOpenSSL($data);
+ break;
+ }
+ }
+
+ public function verifySignature($data, $signature) {
+ switch ($this->cryptParams['library']) {
+ case 'openssl':
+ return $this->verifyOpenSSL($data, $signature);
+ break;
+ }
+ }
+
+ public function getAlgorith() {
+ return $this->cryptParams['method'];
+ }
+
+ static function makeAsnSegment($type, $string) {
+ switch ($type){
+ case 0x02:
+ if (ord($string) > 0x7f)
+ $string = chr(0).$string;
+ break;
+ case 0x03:
+ $string = chr(0).$string;
+ break;
+ }
+
+ $length = strlen($string);
+
+ if ($length < 128){
+ $output = sprintf("%c%c%s", $type, $length, $string);
+ } else if ($length < 0x0100){
+ $output = sprintf("%c%c%c%s", $type, 0x81, $length, $string);
+ } else if ($length < 0x010000) {
+ $output = sprintf("%c%c%c%c%s", $type, 0x82, $length/0x0100, $length%0x0100, $string);
+ } else {
+ $output = NULL;
+ }
+ return($output);
+ }
+
+ /* Modulus and Exponent must already be base64 decoded */
+ static function convertRSA($modulus, $exponent) {
+ /* make an ASN publicKeyInfo */
+ $exponentEncoding = XMLSecurityKey::makeAsnSegment(0x02, $exponent);
+ $modulusEncoding = XMLSecurityKey::makeAsnSegment(0x02, $modulus);
+ $sequenceEncoding = XMLSecurityKey:: makeAsnSegment(0x30, $modulusEncoding.$exponentEncoding);
+ $bitstringEncoding = XMLSecurityKey::makeAsnSegment(0x03, $sequenceEncoding);
+ $rsaAlgorithmIdentifier = pack("H*", "300D06092A864886F70D0101010500");
+ $publicKeyInfo = XMLSecurityKey::makeAsnSegment (0x30, $rsaAlgorithmIdentifier.$bitstringEncoding);
+
+ /* encode the publicKeyInfo in base64 and add PEM brackets */
+ $publicKeyInfoBase64 = base64_encode($publicKeyInfo);
+ $encoding = "-----BEGIN PUBLIC KEY-----\n";
+ $offset = 0;
+ while ($segment=substr($publicKeyInfoBase64, $offset, 64)){
+ $encoding = $encoding.$segment."\n";
+ $offset += 64;
+ }
+ return $encoding."-----END PUBLIC KEY-----\n";
+ }
+
+ public function serializeKey($parent) {
+
+ }
+
+
+
+ /**
+ * Retrieve the X509 certificate this key represents.
+ *
+ * Will return the X509 certificate in PEM-format if this key represents
+ * an X509 certificate.
+ *
+ * @return The X509 certificate or NULL if this key doesn't represent an X509-certificate.
+ */
+ public function getX509Certificate() {
+ return $this->x509Certificate;
+ }
+
+ /* Get the thumbprint of this X509 certificate.
+ *
+ * Returns:
+ * The thumbprint as a lowercase 40-character hexadecimal number, or NULL
+ * if this isn't a X509 certificate.
+ */
+ public function getX509Thumbprint() {
+ return $this->X509Thumbprint;
+ }
+
+
+ /**
+ * Create key from an EncryptedKey-element.
+ *
+ * @param DOMElement $element The EncryptedKey-element.
+ * @return XMLSecurityKey The new key.
+ */
+ public static function fromEncryptedKeyElement(DOMElement $element) {
+
+ $objenc = new XMLSecEnc();
+ $objenc->setNode($element);
+ if (! $objKey = $objenc->locateKey()) {
+ throw new Exception("Unable to locate algorithm for this Encrypted Key");
+ }
+ $objKey->isEncrypted = TRUE;
+ $objKey->encryptedCtx = $objenc;
+ XMLSecEnc::staticLocateKeyInfo($objKey, $element);
+ return $objKey;
+ }
+
+}
+
+class XMLSecurityDSig {
+ const XMLDSIGNS = 'http://www.w3.org/2000/09/xmldsig#';
+ const SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1';
+ const SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256';
+ const SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#sha384';
+ const SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512';
+ const RIPEMD160 = 'http://www.w3.org/2001/04/xmlenc#ripemd160';
+
+ const C14N = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
+ const C14N_COMMENTS = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments';
+ const EXC_C14N = 'http://www.w3.org/2001/10/xml-exc-c14n#';
+ const EXC_C14N_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments';
+
+ const template = '
+
+
+
+';
+
+ public $sigNode = NULL;
+ public $idKeys = array();
+ public $idNS = array();
+ private $signedInfo = NULL;
+ private $xPathCtx = NULL;
+ private $canonicalMethod = NULL;
+ private $prefix = 'ds';
+ private $searchpfx = 'secdsig';
+
+ /* This variable contains an associative array of validated nodes. */
+ private $validatedNodes = NULL;
+
+ public function __construct() {
+ $sigdoc = new DOMDocument();
+ $sigdoc->loadXML(XMLSecurityDSig::template);
+ $this->sigNode = $sigdoc->documentElement;
+ }
+
+ private function resetXPathObj() {
+ $this->xPathCtx = NULL;
+ }
+
+ private function getXPathObj() {
+ if (empty($this->xPathCtx) && ! empty($this->sigNode)) {
+ $xpath = new DOMXPath($this->sigNode->ownerDocument);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $this->xPathCtx = $xpath;
+ }
+ return $this->xPathCtx;
+ }
+
+ static function generate_GUID($prefix='pfx') {
+ $uuid = md5(uniqid(rand(), true));
+ $guid = $prefix.substr($uuid,0,8)."-".
+ substr($uuid,8,4)."-".
+ substr($uuid,12,4)."-".
+ substr($uuid,16,4)."-".
+ substr($uuid,20,12);
+ return $guid;
+ }
+
+ public function locateSignature($objDoc) {
+ if ($objDoc instanceof DOMDocument) {
+ $doc = $objDoc;
+ } else {
+ $doc = $objDoc->ownerDocument;
+ }
+ if ($doc) {
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = ".//secdsig:Signature";
+ $nodeset = $xpath->query($query, $objDoc);
+ $this->sigNode = $nodeset->item(0);
+ return $this->sigNode;
+ }
+ return NULL;
+ }
+
+ public function createNewSignNode($name, $value=NULL) {
+ $doc = $this->sigNode->ownerDocument;
+ if (! is_null($value)) {
+ $node = $doc->createElementNS(XMLSecurityDSig::XMLDSIGNS, $this->prefix.':'.$name, $value);
+ } else {
+ $node = $doc->createElementNS(XMLSecurityDSig::XMLDSIGNS, $this->prefix.':'.$name);
+ }
+ return $node;
+ }
+
+ public function setCanonicalMethod($method) {
+ switch ($method) {
+ case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315':
+ case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments':
+ case 'http://www.w3.org/2001/10/xml-exc-c14n#':
+ case 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments':
+ $this->canonicalMethod = $method;
+ break;
+ default:
+ throw new Exception('Invalid Canonical Method');
+ }
+ if ($xpath = $this->getXPathObj()) {
+ $query = './'.$this->searchpfx.':SignedInfo';
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($sinfo = $nodeset->item(0)) {
+ $query = './'.$this->searchpfx.'CanonicalizationMethod';
+ $nodeset = $xpath->query($query, $sinfo);
+ if (! ($canonNode = $nodeset->item(0))) {
+ $canonNode = $this->createNewSignNode('CanonicalizationMethod');
+ $sinfo->insertBefore($canonNode, $sinfo->firstChild);
+ }
+ $canonNode->setAttribute('Algorithm', $this->canonicalMethod);
+ }
+ }
+ }
+
+ private function canonicalizeData($node, $canonicalmethod, $arXPath=NULL, $prefixList=NULL) {
+ $exclusive = FALSE;
+ $withComments = FALSE;
+ switch ($canonicalmethod) {
+ case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315':
+ $exclusive = FALSE;
+ $withComments = FALSE;
+ break;
+ case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments':
+ $withComments = TRUE;
+ break;
+ case 'http://www.w3.org/2001/10/xml-exc-c14n#':
+ $exclusive = TRUE;
+ break;
+ case 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments':
+ $exclusive = TRUE;
+ $withComments = TRUE;
+ break;
+ }
+ /* Support PHP versions < 5.2 not containing C14N methods in DOM extension */
+ $php_version = explode('.', PHP_VERSION);
+ if (($php_version[0] < 5) || ($php_version[0] == 5 && $php_version[1] < 2) ) {
+ if (! is_null($arXPath)) {
+ throw new Exception("PHP 5.2.0 or higher is required to perform XPath Transformations");
+ }
+ return C14NGeneral($node, $exclusive, $withComments);
+ }
+ return $node->C14N($exclusive, $withComments, $arXPath, $prefixList);
+ }
+
+ public function canonicalizeSignedInfo() {
+
+ $doc = $this->sigNode->ownerDocument;
+ $canonicalmethod = NULL;
+ if ($doc) {
+ $xpath = $this->getXPathObj();
+ $query = "./secdsig:SignedInfo";
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($signInfoNode = $nodeset->item(0)) {
+ $query = "./secdsig:CanonicalizationMethod";
+ $nodeset = $xpath->query($query, $signInfoNode);
+ if ($canonNode = $nodeset->item(0)) {
+ $canonicalmethod = $canonNode->getAttribute('Algorithm');
+ }
+ $this->signedInfo = $this->canonicalizeData($signInfoNode, $canonicalmethod);
+ return $this->signedInfo;
+ }
+ }
+ return NULL;
+ }
+
+ public function calculateDigest ($digestAlgorithm, $data) {
+ switch ($digestAlgorithm) {
+ case XMLSecurityDSig::SHA1:
+ $alg = 'sha1';
+ break;
+ case XMLSecurityDSig::SHA256:
+ $alg = 'sha256';
+ break;
+ case XMLSecurityDSig::SHA384:
+ $alg = 'sha384';
+ break;
+ case XMLSecurityDSig::SHA512:
+ $alg = 'sha512';
+ break;
+ case XMLSecurityDSig::RIPEMD160:
+ $alg = 'ripemd160';
+ break;
+ default:
+ throw new Exception("Cannot validate digest: Unsupported Algorith <$digestAlgorithm>");
+ }
+ if (function_exists('hash')) {
+ return base64_encode(hash($alg, $data, TRUE));
+ } elseif (function_exists('mhash')) {
+ $alg = "MHASH_" . strtoupper($alg);
+ return base64_encode(mhash(constant($alg), $data));
+ } elseif ($alg === 'sha1') {
+ return base64_encode(sha1($data, TRUE));
+ } else {
+ throw new Exception('xmlseclibs is unable to calculate a digest. Maybe you need the mhash library?');
+ }
+ }
+
+ public function validateDigest($refNode, $data) {
+ $xpath = new DOMXPath($refNode->ownerDocument);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = 'string(./secdsig:DigestMethod/@Algorithm)';
+ $digestAlgorithm = $xpath->evaluate($query, $refNode);
+ $digValue = $this->calculateDigest($digestAlgorithm, $data);
+ $query = 'string(./secdsig:DigestValue)';
+ $digestValue = $xpath->evaluate($query, $refNode);
+ return ($digValue == $digestValue);
+ }
+
+ public function processTransforms($refNode, $objData, $includeCommentNodes = TRUE) {
+ $data = $objData;
+ $xpath = new DOMXPath($refNode->ownerDocument);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = './secdsig:Transforms/secdsig:Transform';
+ $nodelist = $xpath->query($query, $refNode);
+ $canonicalMethod = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
+ $arXPath = NULL;
+ $prefixList = NULL;
+ foreach ($nodelist AS $transform) {
+ $algorithm = $transform->getAttribute("Algorithm");
+ switch ($algorithm) {
+ case 'http://www.w3.org/2001/10/xml-exc-c14n#':
+ case 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments':
+
+ if(!$includeCommentNodes) {
+ /* We remove comment nodes by forcing it to use a canonicalization
+ * without comments.
+ */
+ $canonicalMethod = 'http://www.w3.org/2001/10/xml-exc-c14n#';
+ } else {
+ $canonicalMethod = $algorithm;
+ }
+
+ $node = $transform->firstChild;
+ while ($node) {
+ if ($node->localName == 'InclusiveNamespaces') {
+ if ($pfx = $node->getAttribute('PrefixList')) {
+ $arpfx = array();
+ $pfxlist = explode(" ", $pfx);
+ foreach ($pfxlist AS $pfx) {
+ $val = trim($pfx);
+ if (! empty($val)) {
+ $arpfx[] = $val;
+ }
+ }
+ if (count($arpfx) > 0) {
+ $prefixList = $arpfx;
+ }
+ }
+ break;
+ }
+ $node = $node->nextSibling;
+ }
+ break;
+ case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315':
+ case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments':
+ if(!$includeCommentNodes) {
+ /* We remove comment nodes by forcing it to use a canonicalization
+ * without comments.
+ */
+ $canonicalMethod = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
+ } else {
+ $canonicalMethod = $algorithm;
+ }
+
+ break;
+ case 'http://www.w3.org/TR/1999/REC-xpath-19991116':
+ $node = $transform->firstChild;
+ while ($node) {
+ if ($node->localName == 'XPath') {
+ $arXPath = array();
+ $arXPath['query'] = '(.//. | .//@* | .//namespace::*)['.$node->nodeValue.']';
+ $arXpath['namespaces'] = array();
+ $nslist = $xpath->query('./namespace::*', $node);
+ foreach ($nslist AS $nsnode) {
+ if ($nsnode->localName != "xml") {
+ $arXPath['namespaces'][$nsnode->localName] = $nsnode->nodeValue;
+ }
+ }
+ break;
+ }
+ $node = $node->nextSibling;
+ }
+ break;
+ }
+ }
+ if ($data instanceof DOMNode) {
+ $data = $this->canonicalizeData($objData, $canonicalMethod, $arXPath, $prefixList);
+ }
+ return $data;
+ }
+
+ public function processRefNode($refNode) {
+ $dataObject = NULL;
+
+ /*
+ * Depending on the URI, we may not want to include comments in the result
+ * See: http://www.w3.org/TR/xmldsig-core/#sec-ReferenceProcessingModel
+ */
+ $includeCommentNodes = TRUE;
+
+ if ($uri = $refNode->getAttribute("URI")) {
+ $arUrl = parse_url($uri);
+ if (empty($arUrl['path'])) {
+ if ($identifier = $arUrl['fragment']) {
+
+ /* This reference identifies a node with the given id by using
+ * a URI on the form "#identifier". This should not include comments.
+ */
+ $includeCommentNodes = FALSE;
+
+ $xPath = new DOMXPath($refNode->ownerDocument);
+ if ($this->idNS && is_array($this->idNS)) {
+ foreach ($this->idNS AS $nspf=>$ns) {
+ $xPath->registerNamespace($nspf, $ns);
+ }
+ }
+ $iDlist = '@Id="'.$identifier.'"';
+ if (is_array($this->idKeys)) {
+ foreach ($this->idKeys AS $idKey) {
+ $iDlist .= " or @$idKey='$identifier'";
+ }
+ }
+ $query = '//*['.$iDlist.']';
+ $dataObject = $xPath->query($query)->item(0);
+ } else {
+ $dataObject = $refNode->ownerDocument;
+ }
+ } else {
+ $dataObject = file_get_contents($arUrl);
+ }
+ } else {
+ /* This reference identifies the root node with an empty URI. This should
+ * not include comments.
+ */
+ $includeCommentNodes = FALSE;
+
+ $dataObject = $refNode->ownerDocument;
+ }
+ $data = $this->processTransforms($refNode, $dataObject, $includeCommentNodes);
+ if (!$this->validateDigest($refNode, $data)) {
+ return FALSE;
+ }
+
+ if ($dataObject instanceof DOMNode) {
+ /* Add this node to the list of validated nodes. */
+ if(! empty($identifier)) {
+ $this->validatedNodes[$identifier] = $dataObject;
+ } else {
+ $this->validatedNodes[] = $dataObject;
+ }
+ }
+
+ return TRUE;
+ }
+
+ public function getRefNodeID($refNode) {
+ if ($uri = $refNode->getAttribute("URI")) {
+ $arUrl = parse_url($uri);
+ if (empty($arUrl['path'])) {
+ if ($identifier = $arUrl['fragment']) {
+ return $identifier;
+ }
+ }
+ }
+ return null;
+ }
+
+ public function getRefIDs() {
+ $refids = array();
+ $doc = $this->sigNode->ownerDocument;
+
+ $xpath = $this->getXPathObj();
+ $query = "./secdsig:SignedInfo/secdsig:Reference";
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($nodeset->length == 0) {
+ throw new Exception("Reference nodes not found");
+ }
+ foreach ($nodeset AS $refNode) {
+ $refids[] = $this->getRefNodeID($refNode);
+ }
+ return $refids;
+ }
+
+ public function validateReference() {
+ $doc = $this->sigNode->ownerDocument;
+ if (! $doc->isSameNode($this->sigNode)) {
+ $this->sigNode->parentNode->removeChild($this->sigNode);
+ }
+ $xpath = $this->getXPathObj();
+ $query = "./secdsig:SignedInfo/secdsig:Reference";
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($nodeset->length == 0) {
+ throw new Exception("Reference nodes not found");
+ }
+
+ /* Initialize/reset the list of validated nodes. */
+ $this->validatedNodes = array();
+
+ foreach ($nodeset AS $refNode) {
+ if (! $this->processRefNode($refNode)) {
+ /* Clear the list of validated nodes. */
+ $this->validatedNodes = NULL;
+ throw new Exception("Reference validation failed");
+ }
+ }
+ return TRUE;
+ }
+
+ private function addRefInternal($sinfoNode, $node, $algorithm, $arTransforms=NULL, $options=NULL) {
+ $prefix = NULL;
+ $prefix_ns = NULL;
+ $id_name = 'Id';
+ $overwrite_id = TRUE;
+ $force_uri = FALSE;
+
+ if (is_array($options)) {
+ $prefix = empty($options['prefix'])?NULL:$options['prefix'];
+ $prefix_ns = empty($options['prefix_ns'])?NULL:$options['prefix_ns'];
+ $id_name = empty($options['id_name'])?'Id':$options['id_name'];
+ $overwrite_id = !isset($options['overwrite'])?TRUE:(bool)$options['overwrite'];
+ $force_uri = !isset($options['force_uri'])?FALSE:(bool)$options['force_uri'];
+ }
+
+ $attname = $id_name;
+ if (! empty($prefix)) {
+ $attname = $prefix.':'.$attname;
+ }
+
+ $refNode = $this->createNewSignNode('Reference');
+ $sinfoNode->appendChild($refNode);
+
+ if (! $node instanceof DOMDocument) {
+ $uri = NULL;
+ if (! $overwrite_id) {
+ $uri = $node->getAttributeNS($prefix_ns, $id_name);
+ }
+ if (empty($uri)) {
+ $uri = XMLSecurityDSig::generate_GUID();
+ $node->setAttributeNS($prefix_ns, $attname, $uri);
+ }
+ $refNode->setAttribute("URI", '#'.$uri);
+ } elseif ($force_uri) {
+ $refNode->setAttribute("URI", '');
+ }
+
+ $transNodes = $this->createNewSignNode('Transforms');
+ $refNode->appendChild($transNodes);
+
+ if (is_array($arTransforms)) {
+ foreach ($arTransforms AS $transform) {
+ $transNode = $this->createNewSignNode('Transform');
+ $transNodes->appendChild($transNode);
+ if (is_array($transform) &&
+ (! empty($transform['http://www.w3.org/TR/1999/REC-xpath-19991116'])) &&
+ (! empty($transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['query']))) {
+ $transNode->setAttribute('Algorithm', 'http://www.w3.org/TR/1999/REC-xpath-19991116');
+ $XPathNode = $this->createNewSignNode('XPath', $transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['query']);
+ $transNode->appendChild($XPathNode);
+ if (! empty($transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['namespaces'])) {
+ foreach ($transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['namespaces'] AS $prefix => $namespace) {
+ $XPathNode->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:$prefix", $namespace);
+ }
+ }
+ } else {
+ $transNode->setAttribute('Algorithm', $transform);
+ }
+ }
+ } elseif (! empty($this->canonicalMethod)) {
+ $transNode = $this->createNewSignNode('Transform');
+ $transNodes->appendChild($transNode);
+ $transNode->setAttribute('Algorithm', $this->canonicalMethod);
+ }
+
+ $canonicalData = $this->processTransforms($refNode, $node);
+ $digValue = $this->calculateDigest($algorithm, $canonicalData);
+
+ $digestMethod = $this->createNewSignNode('DigestMethod');
+ $refNode->appendChild($digestMethod);
+ $digestMethod->setAttribute('Algorithm', $algorithm);
+
+ $digestValue = $this->createNewSignNode('DigestValue', $digValue);
+ $refNode->appendChild($digestValue);
+ }
+
+ public function addReference($node, $algorithm, $arTransforms=NULL, $options=NULL) {
+ if ($xpath = $this->getXPathObj()) {
+ $query = "./secdsig:SignedInfo";
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($sInfo = $nodeset->item(0)) {
+ $this->addRefInternal($sInfo, $node, $algorithm, $arTransforms, $options);
+ }
+ }
+ }
+
+ public function addReferenceList($arNodes, $algorithm, $arTransforms=NULL, $options=NULL) {
+ if ($xpath = $this->getXPathObj()) {
+ $query = "./secdsig:SignedInfo";
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($sInfo = $nodeset->item(0)) {
+ foreach ($arNodes AS $node) {
+ $this->addRefInternal($sInfo, $node, $algorithm, $arTransforms, $options);
+ }
+ }
+ }
+ }
+
+ public function addObject($data, $mimetype=NULL, $encoding=NULL) {
+ $objNode = $this->createNewSignNode('Object');
+ $this->sigNode->appendChild($objNode);
+ if (! empty($mimetype)) {
+ $objNode->setAtribute('MimeType', $mimetype);
+ }
+ if (! empty($encoding)) {
+ $objNode->setAttribute('Encoding', $encoding);
+ }
+
+ if ($data instanceof DOMElement) {
+ $newData = $this->sigNode->ownerDocument->importNode($data, TRUE);
+ } else {
+ $newData = $this->sigNode->ownerDocument->createTextNode($data);
+ }
+ $objNode->appendChild($newData);
+
+ return $objNode;
+ }
+
+ public function locateKey($node=NULL) {
+ if (empty($node)) {
+ $node = $this->sigNode;
+ }
+ if (! $node instanceof DOMNode) {
+ return NULL;
+ }
+ if ($doc = $node->ownerDocument) {
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = "string(./secdsig:SignedInfo/secdsig:SignatureMethod/@Algorithm)";
+ $algorithm = $xpath->evaluate($query, $node);
+ if ($algorithm) {
+ try {
+ $objKey = new XMLSecurityKey($algorithm, array('type'=>'public'));
+ } catch (Exception $e) {
+ return NULL;
+ }
+ return $objKey;
+ }
+ }
+ return NULL;
+ }
+
+ public function verify($objKey) {
+ $doc = $this->sigNode->ownerDocument;
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = "string(./secdsig:SignatureValue)";
+ $sigValue = $xpath->evaluate($query, $this->sigNode);
+
+ if (empty($sigValue)) {
+ throw new Exception("Unable to locate SignatureValue");
+ }
+ error_log('-->>>>');
+ error_log(print_r($this->signedInfo,1));
+ error_log(print_r($sigValue,1));
+ error_log(print_r($objKey->verifySignature($this->signedInfo, base64_decode($sigValue)), 1));
+
+ return $objKey->verifySignature($this->signedInfo, base64_decode($sigValue));
+ }
+
+ public function signData($objKey, $data) {
+ return $objKey->signData($data);
+ }
+
+ public function sign($objKey, $appendToNode = NULL) {
+ // If we have a parent node append it now so C14N properly works
+ if ($appendToNode != NULL) {
+ $this->resetXPathObj();
+ $this->appendSignature($appendToNode);
+ $this->sigNode = $appendToNode->lastChild;
+ }
+ if ($xpath = $this->getXPathObj()) {
+ $query = "./secdsig:SignedInfo";
+ $nodeset = $xpath->query($query, $this->sigNode);
+ if ($sInfo = $nodeset->item(0)) {
+ $query = "./secdsig:SignatureMethod";
+ $nodeset = $xpath->query($query, $sInfo);
+ $sMethod = $nodeset->item(0);
+ $sMethod->setAttribute('Algorithm', $objKey->type);
+ $data = $this->canonicalizeData($sInfo, $this->canonicalMethod);
+ $sigValue = base64_encode($this->signData($objKey, $data));
+ $sigValueNode = $this->createNewSignNode('SignatureValue', $sigValue);
+ if ($infoSibling = $sInfo->nextSibling) {
+ $infoSibling->parentNode->insertBefore($sigValueNode, $infoSibling);
+ } else {
+ $this->sigNode->appendChild($sigValueNode);
+ }
+ }
+ }
+ }
+
+ public function appendCert() {
+
+ }
+
+ public function appendKey($objKey, $parent=NULL) {
+ $objKey->serializeKey($parent);
+ }
+
+
+ /**
+ * This function inserts the signature element.
+ *
+ * The signature element will be appended to the element, unless $beforeNode is specified. If $beforeNode
+ * is specified, the signature element will be inserted as the last element before $beforeNode.
+ *
+ * @param $node The node the signature element should be inserted into.
+ * @param $beforeNode The node the signature element should be located before.
+ *
+ * @return DOMNode The signature element node
+ */
+ public function insertSignature($node, $beforeNode = NULL) {
+
+ $document = $node->ownerDocument;
+ $signatureElement = $document->importNode($this->sigNode, TRUE);
+
+ if($beforeNode == NULL) {
+ return $node->insertBefore($signatureElement);
+ } else {
+ return $node->insertBefore($signatureElement, $beforeNode);
+ }
+ }
+
+ public function appendSignature($parentNode, $insertBefore = FALSE) {
+ $beforeNode = $insertBefore ? $parentNode->firstChild : NULL;
+ return $this->insertSignature($parentNode, $beforeNode);
+ }
+
+ static function get509XCert($cert, $isPEMFormat=TRUE) {
+ $certs = XMLSecurityDSig::staticGet509XCerts($cert, $isPEMFormat);
+ if (! empty($certs)) {
+ return $certs[0];
+ }
+ return '';
+ }
+
+ static function staticGet509XCerts($certs, $isPEMFormat=TRUE) {
+ if ($isPEMFormat) {
+ $data = '';
+ $certlist = array();
+ $arCert = explode("\n", $certs);
+ $inData = FALSE;
+ foreach ($arCert AS $curData) {
+ if (! $inData) {
+ if (strncmp($curData, '-----BEGIN CERTIFICATE', 22) == 0) {
+ $inData = TRUE;
+ }
+ } else {
+ if (strncmp($curData, '-----END CERTIFICATE', 20) == 0) {
+ $inData = FALSE;
+ $certlist[] = $data;
+ $data = '';
+ continue;
+ }
+ $data .= trim($curData);
+ }
+ }
+ return $certlist;
+ } else {
+ return array($certs);
+ }
+ }
+
+ static function staticAdd509Cert($parentRef, $cert, $isPEMFormat=TRUE, $isURL=False, $xpath=NULL, $options=NULL) {
+ if ($isURL) {
+ $cert = file_get_contents($cert);
+ }
+ if (! $parentRef instanceof DOMElement) {
+ throw new Exception('Invalid parent Node parameter');
+ }
+ $baseDoc = $parentRef->ownerDocument;
+
+ if (empty($xpath)) {
+ $xpath = new DOMXPath($parentRef->ownerDocument);
+ $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
+ }
+
+ $query = "./secdsig:KeyInfo";
+ $nodeset = $xpath->query($query, $parentRef);
+ $keyInfo = $nodeset->item(0);
+ if (! $keyInfo) {
+ $inserted = FALSE;
+ $keyInfo = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:KeyInfo');
+
+ $query = "./secdsig:Object";
+ $nodeset = $xpath->query($query, $parentRef);
+ if ($sObject = $nodeset->item(0)) {
+ $sObject->parentNode->insertBefore($keyInfo, $sObject);
+ $inserted = TRUE;
+ }
+
+ if (! $inserted) {
+ $parentRef->appendChild($keyInfo);
+ }
+ }
+
+ // Add all certs if there are more than one
+ $certs = XMLSecurityDSig::staticGet509XCerts($cert, $isPEMFormat);
+
+ // Attach X509 data node
+ $x509DataNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Data');
+ $keyInfo->appendChild($x509DataNode);
+
+ $issuerSerial = FALSE;
+ $subjectName = FALSE;
+ if (is_array($options)) {
+ if (! empty($options['issuerSerial'])) {
+ $issuerSerial = TRUE;
+ }
+ }
+
+ // Attach all certificate nodes and any additional data
+ foreach ($certs as $X509Cert){
+ if ($issuerSerial) {
+ if ($certData = openssl_x509_parse("-----BEGIN CERTIFICATE-----\n".chunk_split($X509Cert, 64, "\n")."-----END CERTIFICATE-----\n")) {
+ if ($issuerSerial && ! empty($certData['issuer']) && ! empty($certData['serialNumber'])) {
+ if (is_array($certData['issuer'])) {
+ $parts = array();
+ foreach ($certData['issuer'] AS $key => $value) {
+ array_unshift($parts, "$key=$value" . $issuer);
+ }
+ $issuerName = implode(',', $parts);
+ } else {
+ $issuerName = $certData['issuer'];
+ }
+
+ $x509IssuerNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509IssuerSerial');
+ $x509DataNode->appendChild($x509IssuerNode);
+
+ $x509Node = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509IssuerName', $issuerName);
+ $x509IssuerNode->appendChild($x509Node);
+ $x509Node = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509SerialNumber', $certData['serialNumber']);
+ $x509IssuerNode->appendChild($x509Node);
+ }
+ }
+
+ }
+ $x509CertNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Certificate', $X509Cert);
+ $x509DataNode->appendChild($x509CertNode);
+ }
+ }
+
+ public function add509Cert($cert, $isPEMFormat=TRUE, $isURL=False, $options=NULL) {
+ if ($xpath = $this->getXPathObj()) {
+ self::staticAdd509Cert($this->sigNode, $cert, $isPEMFormat, $isURL, $xpath, $options);
+ }
+ }
+
+ /* This function retrieves an associative array of the validated nodes.
+ *
+ * The array will contain the id of the referenced node as the key and the node itself
+ * as the value.
+ *
+ * Returns:
+ * An associative array of validated nodes or NULL if no nodes have been validated.
+ */
+ public function getValidatedNodes() {
+ return $this->validatedNodes;
+ }
+}
+
+class XMLSecEnc {
+ const template = "
+
+
+
+";
+
+ const Element = 'http://www.w3.org/2001/04/xmlenc#Element';
+ const Content = 'http://www.w3.org/2001/04/xmlenc#Content';
+ const URI = 3;
+ const XMLENCNS = 'http://www.w3.org/2001/04/xmlenc#';
+
+ private $encdoc = NULL;
+ private $rawNode = NULL;
+ public $type = NULL;
+ public $encKey = NULL;
+ private $references = array();
+
+ public function __construct() {
+ $this->_resetTemplate();
+ }
+
+ private function _resetTemplate(){
+ $this->encdoc = new DOMDocument();
+ $this->encdoc->loadXML(XMLSecEnc::template);
+ }
+
+ public function addReference($name, $node, $type) {
+ if (! $node instanceOf DOMNode) {
+ throw new Exception('$node is not of type DOMNode');
+ }
+ $curencdoc = $this->encdoc;
+ $this->_resetTemplate();
+ $encdoc = $this->encdoc;
+ $this->encdoc = $curencdoc;
+ $refuri = XMLSecurityDSig::generate_GUID();
+ $element = $encdoc->documentElement;
+ $element->setAttribute("Id", $refuri);
+ $this->references[$name] = array("node" => $node, "type" => $type, "encnode" => $encdoc, "refuri" => $refuri);
+ }
+
+ public function setNode($node) {
+ $this->rawNode = $node;
+ }
+
+ /**
+ * Encrypt the selected node with the given key.
+ *
+ * @param XMLSecurityKey $objKey The encryption key and algorithm.
+ * @param bool $replace Whether the encrypted node should be replaced in the original tree. Default is TRUE.
+ * @return DOMElement The -element.
+ */
+ public function encryptNode($objKey, $replace=TRUE) {
+ $data = '';
+ if (empty($this->rawNode)) {
+ throw new Exception('Node to encrypt has not been set');
+ }
+ if (! $objKey instanceof XMLSecurityKey) {
+ throw new Exception('Invalid Key');
+ }
+ $doc = $this->rawNode->ownerDocument;
+ $xPath = new DOMXPath($this->encdoc);
+ $objList = $xPath->query('/xenc:EncryptedData/xenc:CipherData/xenc:CipherValue');
+ $cipherValue = $objList->item(0);
+ if ($cipherValue == NULL) {
+ throw new Exception('Error locating CipherValue element within template');
+ }
+ switch ($this->type) {
+ case (XMLSecEnc::Element):
+ $data = $doc->saveXML($this->rawNode);
+ $this->encdoc->documentElement->setAttribute('Type', XMLSecEnc::Element);
+ break;
+ case (XMLSecEnc::Content):
+ $children = $this->rawNode->childNodes;
+ foreach ($children AS $child) {
+ $data .= $doc->saveXML($child);
+ }
+ $this->encdoc->documentElement->setAttribute('Type', XMLSecEnc::Content);
+ break;
+ default:
+ throw new Exception('Type is currently not supported');
+ return;
+ }
+
+ $encMethod = $this->encdoc->documentElement->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:EncryptionMethod'));
+ $encMethod->setAttribute('Algorithm', $objKey->getAlgorith());
+ $cipherValue->parentNode->parentNode->insertBefore($encMethod, $cipherValue->parentNode->parentNode->firstChild);
+
+ $strEncrypt = base64_encode($objKey->encryptData($data));
+ $value = $this->encdoc->createTextNode($strEncrypt);
+ $cipherValue->appendChild($value);
+
+ if ($replace) {
+ switch ($this->type) {
+ case (XMLSecEnc::Element):
+ if ($this->rawNode->nodeType == XML_DOCUMENT_NODE) {
+ return $this->encdoc;
+ }
+ $importEnc = $this->rawNode->ownerDocument->importNode($this->encdoc->documentElement, TRUE);
+ $this->rawNode->parentNode->replaceChild($importEnc, $this->rawNode);
+ return $importEnc;
+ break;
+ case (XMLSecEnc::Content):
+ $importEnc = $this->rawNode->ownerDocument->importNode($this->encdoc->documentElement, TRUE);
+ while($this->rawNode->firstChild) {
+ $this->rawNode->removeChild($this->rawNode->firstChild);
+ }
+ $this->rawNode->appendChild($importEnc);
+ return $importEnc;
+ break;
+ }
+ } else {
+ return $this->encdoc->documentElement;
+ }
+ }
+
+ public function encryptReferences($objKey) {
+ $curRawNode = $this->rawNode;
+ $curType = $this->type;
+ foreach ($this->references AS $name=>$reference) {
+ $this->encdoc = $reference["encnode"];
+ $this->rawNode = $reference["node"];
+ $this->type = $reference["type"];
+ try {
+ $encNode = $this->encryptNode($objKey);
+ $this->references[$name]["encnode"] = $encNode;
+ } catch (Exception $e) {
+ $this->rawNode = $curRawNode;
+ $this->type = $curType;
+ throw $e;
+ }
+ }
+ $this->rawNode = $curRawNode;
+ $this->type = $curType;
+ }
+
+ /**
+ * Retrieve the CipherValue text from this encrypted node.
+ *
+ * @return string|NULL The Ciphervalue text, or NULL if no CipherValue is found.
+ */
+ public function getCipherValue() {
+ if (empty($this->rawNode)) {
+ throw new Exception('Node to decrypt has not been set');
+ }
+
+ $doc = $this->rawNode->ownerDocument;
+ $xPath = new DOMXPath($doc);
+ $xPath->registerNamespace('xmlencr', XMLSecEnc::XMLENCNS);
+ /* Only handles embedded content right now and not a reference */
+ $query = "./xmlencr:CipherData/xmlencr:CipherValue";
+ $nodeset = $xPath->query($query, $this->rawNode);
+ $node = $nodeset->item(0);
+
+ if (!$node) {
+ return NULL;
+ }
+
+ return base64_decode($node->nodeValue);
+ }
+
+ /**
+ * Decrypt this encrypted node.
+ *
+ * The behaviour of this function depends on the value of $replace.
+ * If $replace is FALSE, we will return the decrypted data as a string.
+ * If $replace is TRUE, we will insert the decrypted element(s) into the
+ * document, and return the decrypted element(s).
+ *
+ * @params XMLSecurityKey $objKey The decryption key that should be used when decrypting the node.
+ * @params boolean $replace Whether we should replace the encrypted node in the XML document with the decrypted data. The default is TRUE.
+ * @return string|DOMElement The decrypted data.
+ */
+ public function decryptNode($objKey, $replace=TRUE) {
+ if (! $objKey instanceof XMLSecurityKey) {
+ throw new Exception('Invalid Key');
+ }
+
+ $encryptedData = $this->getCipherValue();
+ if ($encryptedData) {
+ $decrypted = $objKey->decryptData($encryptedData);
+ if ($replace) {
+ switch ($this->type) {
+ case (XMLSecEnc::Element):
+ $newdoc = new DOMDocument();
+ $newdoc->loadXML($decrypted);
+ if ($this->rawNode->nodeType == XML_DOCUMENT_NODE) {
+ return $newdoc;
+ }
+ $importEnc = $this->rawNode->ownerDocument->importNode($newdoc->documentElement, TRUE);
+ $this->rawNode->parentNode->replaceChild($importEnc, $this->rawNode);
+ return $importEnc;
+ break;
+ case (XMLSecEnc::Content):
+ if ($this->rawNode->nodeType == XML_DOCUMENT_NODE) {
+ $doc = $this->rawNode;
+ } else {
+ $doc = $this->rawNode->ownerDocument;
+ }
+ $newFrag = $doc->createDocumentFragment();
+ $newFrag->appendXML($decrypted);
+ $parent = $this->rawNode->parentNode;
+ $parent->replaceChild($newFrag, $this->rawNode);
+ return $parent;
+ break;
+ default:
+ return $decrypted;
+ }
+ } else {
+ return $decrypted;
+ }
+ } else {
+ throw new Exception("Cannot locate encrypted data");
+ }
+ }
+
+ public function encryptKey($srcKey, $rawKey, $append=TRUE) {
+ if ((! $srcKey instanceof XMLSecurityKey) || (! $rawKey instanceof XMLSecurityKey)) {
+ throw new Exception('Invalid Key');
+ }
+ $strEncKey = base64_encode($srcKey->encryptData($rawKey->key));
+ $root = $this->encdoc->documentElement;
+ $encKey = $this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:EncryptedKey');
+ if ($append) {
+ $keyInfo = $root->insertBefore($this->encdoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyInfo'), $root->firstChild);
+ $keyInfo->appendChild($encKey);
+ } else {
+ $this->encKey = $encKey;
+ }
+ $encMethod = $encKey->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:EncryptionMethod'));
+ $encMethod->setAttribute('Algorithm', $srcKey->getAlgorith());
+ if (! empty($srcKey->name)) {
+ $keyInfo = $encKey->appendChild($this->encdoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyInfo'));
+ $keyInfo->appendChild($this->encdoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyName', $srcKey->name));
+ }
+ $cipherData = $encKey->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:CipherData'));
+ $cipherData->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:CipherValue', $strEncKey));
+ if (is_array($this->references) && count($this->references) > 0) {
+ $refList = $encKey->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:ReferenceList'));
+ foreach ($this->references AS $name=>$reference) {
+ $refuri = $reference["refuri"];
+ $dataRef = $refList->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:DataReference'));
+ $dataRef->setAttribute("URI", '#' . $refuri);
+ }
+ }
+ return;
+ }
+
+ public function decryptKey($encKey) {
+ if (! $encKey->isEncrypted) {
+ throw new Exception("Key is not Encrypted");
+ }
+ if (empty($encKey->key)) {
+ throw new Exception("Key is missing data to perform the decryption");
+ }
+ return $this->decryptNode($encKey, FALSE);
+ }
+
+ public function locateEncryptedData($element) {
+ if ($element instanceof DOMDocument) {
+ $doc = $element;
+ } else {
+ $doc = $element->ownerDocument;
+ }
+ if ($doc) {
+ $xpath = new DOMXPath($doc);
+ $query = "//*[local-name()='EncryptedData' and namespace-uri()='".XMLSecEnc::XMLENCNS."']";
+ $nodeset = $xpath->query($query);
+ return $nodeset->item(0);
+ }
+ return NULL;
+ }
+
+ public function locateKey($node=NULL) {
+ if (empty($node)) {
+ $node = $this->rawNode;
+ }
+ if (! $node instanceof DOMNode) {
+ return NULL;
+ }
+ if ($doc = $node->ownerDocument) {
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('xmlsecenc', XMLSecEnc::XMLENCNS);
+ $query = ".//xmlsecenc:EncryptionMethod";
+ $nodeset = $xpath->query($query, $node);
+ if ($encmeth = $nodeset->item(0)) {
+ $attrAlgorithm = $encmeth->getAttribute("Algorithm");
+ try {
+ $objKey = new XMLSecurityKey($attrAlgorithm, array('type'=>'private'));
+ } catch (Exception $e) {
+ return NULL;
+ }
+ return $objKey;
+ }
+ }
+ return NULL;
+ }
+
+ static function staticLocateKeyInfo($objBaseKey=NULL, $node=NULL) {
+ if (empty($node) || (! $node instanceof DOMNode)) {
+ return NULL;
+ }
+ $doc = $node->ownerDocument;
+ if (!$doc) {
+ return NULL;
+ }
+
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('xmlsecenc', XMLSecEnc::XMLENCNS);
+ $xpath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS);
+ $query = "./xmlsecdsig:KeyInfo";
+ $nodeset = $xpath->query($query, $node);
+ $encmeth = $nodeset->item(0);
+ if (!$encmeth) {
+ /* No KeyInfo in EncryptedData / EncryptedKey. */
+ return $objBaseKey;
+ }
+
+ foreach ($encmeth->childNodes AS $child) {
+ switch ($child->localName) {
+ case 'KeyName':
+ if (! empty($objBaseKey)) {
+ $objBaseKey->name = $child->nodeValue;
+ }
+ break;
+ case 'KeyValue':
+ foreach ($child->childNodes AS $keyval) {
+ switch ($keyval->localName) {
+ case 'DSAKeyValue':
+ throw new Exception("DSAKeyValue currently not supported");
+ break;
+ case 'RSAKeyValue':
+ $modulus = NULL;
+ $exponent = NULL;
+ if ($modulusNode = $keyval->getElementsByTagName('Modulus')->item(0)) {
+ $modulus = base64_decode($modulusNode->nodeValue);
+ }
+ if ($exponentNode = $keyval->getElementsByTagName('Exponent')->item(0)) {
+ $exponent = base64_decode($exponentNode->nodeValue);
+ }
+ if (empty($modulus) || empty($exponent)) {
+ throw new Exception("Missing Modulus or Exponent");
+ }
+ $publicKey = XMLSecurityKey::convertRSA($modulus, $exponent);
+ $objBaseKey->loadKey($publicKey);
+ break;
+ }
+ }
+ break;
+ case 'RetrievalMethod':
+ $type = $child->getAttribute('Type');
+ if ($type !== 'http://www.w3.org/2001/04/xmlenc#EncryptedKey') {
+ /* Unsupported key type. */
+ break;
+ }
+ $uri = $child->getAttribute('URI');
+ if ($uri[0] !== '#') {
+ /* URI not a reference - unsupported. */
+ break;
+ }
+ $id = substr($uri, 1);
+
+ $query = "//xmlsecenc:EncryptedKey[@Id='$id']";
+ $keyElement = $xpath->query($query)->item(0);
+ if (!$keyElement) {
+ throw new Exception("Unable to locate EncryptedKey with @Id='$id'.");
+ }
+
+ return XMLSecurityKey::fromEncryptedKeyElement($keyElement);
+ case 'EncryptedKey':
+ return XMLSecurityKey::fromEncryptedKeyElement($child);
+ case 'X509Data':
+ if ($x509certNodes = $child->getElementsByTagName('X509Certificate')) {
+ if ($x509certNodes->length > 0) {
+ $x509cert = $x509certNodes->item(0)->textContent;
+ $x509cert = str_replace(array("\r", "\n"), "", $x509cert);
+ $x509cert = "-----BEGIN CERTIFICATE-----\n".chunk_split($x509cert, 64, "\n")."-----END CERTIFICATE-----\n";
+ $objBaseKey->loadKey($x509cert, FALSE, TRUE);
+ }
+ }
+ break;
+ }
+ }
+ return $objBaseKey;
+ }
+
+ public function locateKeyInfo($objBaseKey=NULL, $node=NULL) {
+ if (empty($node)) {
+ $node = $this->rawNode;
+ }
+ return XMLSecEnc::staticLocateKeyInfo($objBaseKey, $node);
+ }
+}
diff --git a/plugin/sepe/uninstall.php b/plugin/sepe/uninstall.php
new file mode 100644
index 0000000000..80ea6dcb2a
--- /dev/null
+++ b/plugin/sepe/uninstall.php
@@ -0,0 +1,13 @@
+uninstall();
diff --git a/plugin/sepe/view/accion_formativa.tpl b/plugin/sepe/view/accion_formativa.tpl
new file mode 100644
index 0000000000..1bb8111671
--- /dev/null
+++ b/plugin/sepe/view/accion_formativa.tpl
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+ {% if message_info != "" %}
+
+ {{ message_info }}
+
+ {% endif %}
+ {% if message_error != "" %}
+
+ {{ message_error }}
+
+ {% endif %}
+
+
+
+
+
+
diff --git a/plugin/sepe/view/configuracion.tpl b/plugin/sepe/view/configuracion.tpl
new file mode 100644
index 0000000000..a22d4f4fc4
--- /dev/null
+++ b/plugin/sepe/view/configuracion.tpl
@@ -0,0 +1,40 @@
+
+
+
+
diff --git a/plugin/sepe/view/datos_identificativos.tpl b/plugin/sepe/view/datos_identificativos.tpl
new file mode 100644
index 0000000000..fed7056ddb
--- /dev/null
+++ b/plugin/sepe/view/datos_identificativos.tpl
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+ {% if message_info != "" %}
+
+ {{ message_info }}
+
+ {% endif %}
+ {% if message_error != "" %}
+
+ {{ message_error }}
+
+ {% endif %}
+
+
+
diff --git a/plugin/sepe/view/editar_accion_formativa.tpl b/plugin/sepe/view/editar_accion_formativa.tpl
new file mode 100644
index 0000000000..e587883a0f
--- /dev/null
+++ b/plugin/sepe/view/editar_accion_formativa.tpl
@@ -0,0 +1,357 @@
+
+
+
diff --git a/plugin/sepe/view/editar_datos_identificativos.tpl b/plugin/sepe/view/editar_datos_identificativos.tpl
new file mode 100644
index 0000000000..b99670f08b
--- /dev/null
+++ b/plugin/sepe/view/editar_datos_identificativos.tpl
@@ -0,0 +1,89 @@
+
+
+
+
+
diff --git a/plugin/sepe/view/editar_especialidad_accion.tpl b/plugin/sepe/view/editar_especialidad_accion.tpl
new file mode 100644
index 0000000000..e84c642f94
--- /dev/null
+++ b/plugin/sepe/view/editar_especialidad_accion.tpl
@@ -0,0 +1,435 @@
+
+
+
+
+
+
diff --git a/plugin/sepe/view/editar_especialidad_classroom.tpl b/plugin/sepe/view/editar_especialidad_classroom.tpl
new file mode 100644
index 0000000000..284ebedfff
--- /dev/null
+++ b/plugin/sepe/view/editar_especialidad_classroom.tpl
@@ -0,0 +1,95 @@
+
+
+
+
+